I have written a crossword game with thousands of lines of code in a single file. I find it really inconvenient to find functions and manage it. I tried to split the functions into several files but it failed because of global variables (which are used in lots of functions). Are there any ways to solve that?
Use the extern keyword. With this keyword you can tell the compiler that the variable has external linkage (variable is declared somewere else but visible in this file):
file1.c: int foo;
file2.c: extern int foo;
foo is declared in file1 but can also be used in file2
I get hundreds of errors...
Most of them are "redefinition of `current'", redefinition of a global variable
Code:
#define SUBJECT 3
#define NUM_TYPE 4
#define PERPAGE 8
#define MAX 152621
#define MAX_USER 20
#define SCREENWIDTH 90
#define SCREENHEIGHT 35
#define INTEGER 1
#define DOUBLE 2
#define STRING 3
#define NOBEST 0
#define LARGER 1
#define SMALLER 2
#define LONGER 3
#define SHORTER 4
#include <stdio.h> //STANDARD INPUT & OUTPUT HEADER
#include <string.h> //STRING PROCESSING HEADER
#include <stdlib.h> //STANDARD LIBRARY HEADER
#include <time.h> //TIME HEADER
#include <sys/timeb.h> //TIMEB HEADER
#include <ctype.h> //CHARACTER PROCESSING HANDER
#include <windows.h> //WINDOWS HEADER
#include <math.h> //MATHS FUNCTION HEADER
#include <unistd.h> //STANDARD SYMBOLIC CONSTANTS AND TYPES
#include "colortext.h" //COLOUR TEXT GENERATING HEADER
//the files that I split
#include "01_crossword.c"
#include "02_freepuzzle.c"
#include "03_bookworm.c"
#include "04_target.c"
#include "11_highscore.c"
#include "12_statistics.c"
#include "13_settings.c"
#include "21_users.c"
#include "71_tools.c"
//structure -- crossword words in database (the word, and its hint)
struct words{
char word[21], detail[200];
int used, dif;
};
//structure -- answer of crossword and freepuzzle
struct answer{
char word[21], hint[200];
int pos[2];
int times, num_hint, dif;//for crossword
int end[2], length; //for freepuzzle
};
//structure -- coordinates of different positions of same words
struct result_form{
int co[50][2];
};
//structure -- name, password and games statistics of users
struct statistics{
char name[256], password[256];
int c_total, c_win, c_lose, c_wordfill, c_cate[SUBJECT];
int f_total, f_win, f_lose, f_wordfill;
int b_total, b_lose, b_hscore_score;
int t_total, t_nine;
double c_averwordfill, c_time, c_avertime, c_score, c_averscore;
double f_averwordfill, f_time, f_avertime, f_score, f_averscore;
double b_score, b_averscore;
double t_averfound, t_score, t_averscore;
char b_lword[20], b_hscore_word[20];
};
//structure -- settings
struct settings{
int category, isSaveStat, type, isDisplay;
};
//structure -- highscore list for the four games
struct highscorelist{
double score;
char name[20], category[10];
int date[3];
int level;
};
//GLOBAL VARIABLES
char plane[15][20]; //the cells of the puzzle
int count; //number of words in the data.dat
int num; //number of words generated for the puzzle
int num_users=0; //total number of users
int current=-1; //ID of current user
int filled[14]; //if the word has been filled already
int px, py; //for gotoxy
int ref[14]={3, 6, 0, 4, 1, 2, 5, 0, 1, 3, 2, 6, 4, 5};
//reference id for ans (crossword)
int num_result; //Number of results found of word in Bookworm
int fcolour[7][8]; //Forecolour of letters in table in Bookworm
int bcolour[7][8]; //Backcolour of letters in table in Bookworm
int level; //The Level in Bookworm
int lscore[26]={40, 85, 80, 70, 40, 120, 70, 115, 40, 230, 160, 45, 85,
40, 40, 85, 250, 45, 35, 40, 40, 130, 120, 270, 120, 300};
//Score of letters in Bookworm
int timed[6]; //store the current time: Y M D H M S
int restrict[3]; //Restricted coordinates in FreePuzzle
char title[40]="Crossword Puzzle";
char type[NUM_TYPE][20]={"Crossword Puzzle", "Target",
"Free Puzzle", "Bookworm"};
char cat[SUBJECT][10]={"Computer", "Biology", "Maths"};
char ans_target[10]; //the nine-letter word of Target
char wordlist[60000][11]; //the word list of Target
char whole[26][3]={"??\0", "??\0", "??\0", "??\0", "??\0", "??\0", "??\0",
"??\0", "??\0", "??\0", "??\0", "??\0", "??\0", "??\0",
"??\0", "??\0", "Qu\0", "??\0", "??\0", "??\0", "??\0",
"??\0", "??\0", "??\0", "??\0", "??\0"};
double starttime, endtime; //for timer
struct words data[500];
struct answer ans[2][7]; //ans[0][x] is across, ans[1][x] is down
struct result_form result_co[20];
struct statistics stat[MAX_USER];
struct statistics all;
struct settings set;
struct highscorelist highscore_crossword[10];
struct highscorelist highscore_target[10];
struct highscorelist highscore_freepuzzle[10];
struct highscorelist highscore_bookworm[10];
In my trial, I inserted the following code to my included file:
Code:
//GLOBAL VARIABLES
extern char plane[15][20]; //the cells of the puzzle
extern int count; //number of words in the data.dat
extern int num; //number of words generated for the puzzle
extern int num_users=0; //total number of users
extern int current=-1; //ID of current user
extern int filled[14]; //if the word has been filled already
extern int px, py; //for gotoxy
extern int ref[14]={3, 6, 0, 4, 1, 2, 5, 0, 1, 3, 2, 6, 4, 5};
//reference id for ans (crossword)
extern int num_result; //Number of results found of word in Bookworm
extern int fcolour[7][8]; //Forecolour of letters in table in Bookworm
extern int bcolour[7][8]; //Backcolour of letters in table in Bookworm
extern int level; //The Level in Bookworm
extern int lscore[26]={40, 85, 80, 70, 40, 120, 70, 115, 40, 230, 160, 45, 85,
40, 40, 85, 250, 45, 35, 40, 40, 130, 120, 270, 120, 300};
//Score of letters in Bookworm
extern int timed[6]; //store the current time: Y M D H M S
extern int restrict[3]; //Restricted coordinates in FreePuzzle
extern char title[40]="Crossword Puzzle";
extern char type[NUM_TYPE][20]={"Crossword Puzzle", "Target",
"Free Puzzle", "Bookworm"};
extern char cat[SUBJECT][10]={"Computer", "Biology", "Maths"};
extern char ans_target[10]; //the nine-letter word of Target
extern char wordlist[60000][11]; //the word list of Target
extern char whole[26][3]={"??\0", "??\0", "??\0", "??\0", "??\0", "??\0", "??\0",
"??\0", "??\0", "??\0", "??\0", "??\0", "??\0", "??\0",
"??\0", "??\0", "Qu\0", "??\0", "??\0", "??\0", "??\0",
"??\0", "??\0", "??\0", "??\0", "??\0"};
extern double starttime, endtime; //for timer
extern struct words data[500];
extern struct answer ans[2][7]; //ans[0][x] is across, ans[1][x] is down
extern struct result_form result_co[20];
extern struct statistics stat[MAX_USER];
extern struct statistics all;
extern struct settings set;
extern struct highscorelist highscore_crossword[10];
extern struct highscorelist highscore_target[10];
extern struct highscorelist highscore_freepuzzle[10];
extern struct highscorelist highscore_bookworm[10];
What should I do with the struct, do I need to type all the variables in each struct again?
And... Do I need to #define the variables again?
"Appendix":
I get these errors (extracted)... all are about struct
D:\my programs\crossword_1.1\01_crossword.c: In function `init_crossword':
D:\my programs\crossword_1.1\01_crossword.c:107: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:112: invalid use of undefined type `struct answer'
D:\my programs\crossword_1.1\01_crossword.c:113: invalid use of undefined type `struct answer'
D:\my programs\crossword_1.1\01_crossword.c: In function `read_crossword':
D:\my programs\crossword_1.1\01_crossword.c:126: invalid use of undefined type `struct settings'
D:\my programs\crossword_1.1\01_crossword.c:126: invalid use of undefined type `struct settings'
D:\my programs\crossword_1.1\01_crossword.c:127: invalid use of undefined type `struct settings'
D:\my programs\crossword_1.1\01_crossword.c:130: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:133: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:136: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:137: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c: In function `pre_crossword':
D:\my programs\crossword_1.1\01_crossword.c:152: invalid use of undefined type `struct settings'
D:\my programs\crossword_1.1\01_crossword.c: In function `generate':
D:\my programs\crossword_1.1\01_crossword.c:187: invalid use of undefined type `struct answer'
D:\my programs\crossword_1.1\01_crossword.c:187: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:188: invalid use of undefined type `struct answer'
D:\my programs\crossword_1.1\01_crossword.c:188: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:189: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:191: invalid use of undefined type `struct words'
D:\my programs\crossword_1.1\01_crossword.c:193: invalid use of undefined type `struct answer'
Thank you! I have solved the problem successfully.
Here are a few points to note:
a) the variables declared by extern must not have an initial value
b) the structure only needs to be declared once at the beginning (the one listing all the variables inside a structure)
c) for the functions, use a new file to store all the declaration of functions and include this file at the very beginning, otherwise there will be errors like "conflicting types of function..." (I don't know if this is the best way to solve this problem)
Maybe some of my conclusions are not correct, please point them out if I have any.