当两个程序都需要某些变量时,将C程序拆分为单独的文件

当两个程序都需要某些变量时,将C程序拆分为单独的文件,c,file,global-variables,C,File,Global Variables,我正试图找出如何将一个程序拆分成不同的组件,这给我带来了很多麻烦。我有一个命令行游戏,我想分为一个设置文件和一个游戏文件 分离功能很容易,但处理两个程序都需要的这两个变量已被证明是困难的。我需要目录变量和房间变量可以从游戏文件中访问 我觉得我必须错过一些明显的东西。我尝试了extern,尝试将变量写入临时文件,但每次尝试都会遇到一些问题。最直接的方法是什么 使用extern时,使用gcc-oprog.c-lpthread编译时出错 extern char directory[20]; exter

我正试图找出如何将一个程序拆分成不同的组件,这给我带来了很多麻烦。我有一个命令行游戏,我想分为一个设置文件和一个游戏文件

分离功能很容易,但处理两个程序都需要的这两个变量已被证明是困难的。我需要
目录
变量和
房间
变量可以从游戏文件中访问

我觉得我必须错过一些明显的东西。我尝试了
extern
,尝试将变量写入临时文件,但每次尝试都会遇到一些问题。最直接的方法是什么

使用
extern
时,使用
gcc-oprog.c-lpthread编译时出错

extern char directory[20];
extern char *rooms[7];
错误:

5 warnings generated.
Undefined symbols for architecture x86_64:
  "_directory", referenced from:
      _createRooms in eldridgt-6bd105.o
      _connectionsToFiles in eldridgt-6bd105.o
      _roomTypesToFiles in eldridgt-6bd105.o
  "_rooms", referenced from:
      _createRooms in eldridgt-6bd105.o
      _connectionsToFiles in eldridgt-6bd105.o
      _roomTypesToFiles in eldridgt-6bd105.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>

struct stat st = {0};
const char * ROOM_NAMES[] = {"Water", "Fire", "Wind", "Earth", "Plasma", "DarkMatter", "Air", "Ice", "Rock", "Lava"};
int i,j;
char directory[20];
char *rooms[7];
int connections[7][7] = {0};
int totalMoves = 0;
char roomChoice[20];
char *movesRecord[100];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void getRoomChoice() {
    fflush(stdin);
    scanf("%s", roomChoice);
    fflush(stdin);
    fflush(stdout);
}

void * getTime(void *arg) {
    pthread_mutex_lock(&mutex);
    FILE *file = fopen("currentTime.txt", "w");
    time_t curtime;
    struct tm *loc_time;
    curtime = time (NULL);
    loc_time = localtime (&curtime);
    fprintf(file, "%s\n", asctime (loc_time));
    fclose(file);
    pthread_mutex_unlock(&mutex);
}

void * createRooms() {
  // Create directory
  int pid = getpid();
  char prefix[] = "eldridgt.";
  sprintf(directory, "%s%d", prefix, pid);
  if (stat(directory, &st) == -1) {
    mkdir(directory, 0700);
  }

  // Get random non-repeating array from 0-6
    int randArray[10];
    int x, p;
    int count;
    int i=0;
    srand(time(NULL)); // Random seed
    for(count=0;count<10;count++){
            randArray[count]=rand()%10+1;
    }
    while(i<7){
            int r=rand()%7;
            for (x = 0; x < i; x++) {
                    if(randArray[x]==r){
                            break;
                    }
            }
            if(x==i){
                    randArray[i++]=r;
            }
    }

    // Create room files
  for(i=0; i<7; i++) {
    int random;
        int x;
        int randomArray[7];
    char filePath[100];
    int connectionArr[10];
    memset(connectionArr, 0, sizeof connectionArr);
    random = randArray[i];
    if (connectionArr[random] == 0) { // If room not used
      sprintf(filePath,"%s/%s", directory, ROOM_NAMES[random]);
      FILE *file = fopen(filePath, "ab+");
      fprintf(file, "ROOM NAME: %s\n", ROOM_NAMES[random]); // Add room name
      fclose(file);
      rooms[i] = ROOM_NAMES[random];
      connectionArr[random] = 1; // Room has been used
    }
  }
  return rooms;
}

void * createConnections() {
    for(i=0; i<7; i++) {
        int connectionCount = rand() % 4 + 3; // Random number 3-6
        int currentCount = 0;
        for(j=0; j<7; j++) {
            currentCount = currentCount + connections[i][j];
        }
        while (currentCount < connectionCount+1) {
            int random = rand() % 7;
            while (random == i) {
                random = rand() % 7; // If random == current, reset random
            }
      // Set connections between both rooms
            connections[i][random] = 1;
            connections[random][i] = 1;
            currentCount++;
        }
    }
}

void * connectionsToFiles() {
    for(i=0; i<7; i++) {
        int connectionCount = 1;
        for(j=0; j<7; j++) {
            if(connections[i][j] == 1) {
        char filePath[100];
                sprintf(filePath,"%s/%s", directory, rooms[i]);
                FILE *file = fopen(filePath, "ab+");
                fprintf(file, "CONNECTION %d: %s\n", connectionCount, rooms[j]);
                fclose(file);
                connectionCount++;
            }
        }
    }
}

void * roomTypesToFiles() {
    for(i=0; i<7; i++) {
    char filePath[100];
        sprintf(filePath,"%s/%s", directory, rooms[i]);
        FILE *file = fopen(filePath, "a");
    switch(i) {
      case 0 :
        fprintf(file, "ROOM TYPE: START_ROOM\n");
        break;
      case 6 :
        fprintf(file, "ROOM TYPE: END_ROOM\n");
        break;
      default :
        fprintf(file, "ROOM TYPE: MID_ROOM\n");
    }
        fclose(file);
    }
}

isEndRoom(idx) {
    movesRecord[totalMoves - 1] = rooms[idx];
  char filePath[100];
    sprintf(filePath,"%s/%s", directory, rooms[idx]);
    char roomType[20];
    int lineNumber = 1;
    FILE *file = fopen(filePath, "r");
    int totaLines = 0;
    char line[256];
    while(fgets(line, sizeof line, file) != NULL) {
        totaLines++; // Line count of room file
    }
    fclose(file);

    file = fopen(filePath, "r");
    while(fgets(line, sizeof line, file) != NULL) {
        if(lineNumber == totaLines) {
      int length = strlen(line) - 11;
            strncpy(roomType, line+11, length);
            roomType[length-1] = '\0';
        }
        lineNumber++;
    }

    // Check if this is the end room
    if(strncmp(roomType, "END", 3) == 0) {
    printf("YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!\n");
    printf("YOU TOOK %d STEPS. YOUR PATH TO VICTORY WAS:\n", totalMoves - 1);
    for(i=1; i<totalMoves; i++) {
      printf("%s\n", movesRecord[i]);
    }
        return 1; // End was reached
    } else {
    return 0; // End was not reached
  }
}

void * playGame(idx) {
  totalMoves++;
  printf("\n");
    if(isEndRoom(idx)) {
        exit(0);
    }

    while(1) {
    char filePath[100];
        sprintf(filePath,"%s/%s", directory, rooms[idx]);

        FILE *file = fopen(filePath, "r");
        int totaLines = 0;
        char line[100];
        while(fgets(line, sizeof line, file) != NULL) {
            totaLines++; // Line count of room file
        }
        fclose(file);

        file = fopen(filePath, "r");
        int lineNumber = 0;
        char *roomChoices[6][20];
        while(fgets(line, sizeof line, file) != NULL) { // Current room name
            if(lineNumber == 0) {
                char roomName[20];
        int length = strlen(line) - 11;
            strncpy(roomName, line+11, length);
            roomName[length-1] = '\0';
                printf("CURRENT LOCATION: %s\n", roomName);
            }
            else if(lineNumber == 1) { // First room choice option
                printf("POSSIBLE CONNECTIONS: ");
                fflush(stdout);
                char roomName[20];
        int length = strlen(line) - 14;
            strncpy(roomName, line+14, length);
            roomName[length-1] = '\0';
                printf("%s", roomName);
                strcpy(roomChoices[lineNumber - 1], roomName);
            }
            else if(lineNumber > 1 && lineNumber < totaLines - 1) { // Subsequent room choice options
                printf(", ");
                fflush(stdout);
                char roomName[20];
        int length = strlen(line) - 14;
            strncpy(roomName, line+14, length);
            roomName[length-1] = '\0';
                printf("%s", roomName);
                fflush(stdout);
                strcpy(roomChoices[lineNumber - 1], roomName);
            }
            else {
                printf(".");
                fflush(stdout);
            }
            lineNumber++;
        }
        fclose(file);
        printf("\nWHERE TO? >");
        getRoomChoice(); // Get next room choice
        if (strcmp(roomChoice, "time") == 0) {
            pthread_t thread;
            int rc = pthread_create(&thread, NULL, &getTime, NULL);
            if (rc) {
                    printf("ERROR; return code from pthread_create() is %d\n", rc);
                    exit(-1);
            }
            sleep(1);
            FILE *file = fopen("currentTime.txt", "r");
            char currentTime[50];
            fgets(currentTime, sizeof currentTime, file);
            printf("\n%s\n", currentTime);
        } else {
                for(i=0; i<totaLines-2; i++) {
                    if(strcmp(roomChoices[i], roomChoice) == 0) {
                        for(j=0; j<7; j++) {
                            if(strcmp(rooms[j], roomChoice) == 0) { // If the room is equal to roomChoice
                                playGame(j); // Make playGame call for new room
                            }
                        }
                    }
                }
                printf("\nHUH? I DON’T UNDERSTAND THAT ROOM. TRY AGAIN.\n\n");
                fflush(stdout);
                fflush(stdin);
        }
    }
}

int main() {
    createRooms();
    createConnections();
    connectionsToFiles();
    roomTypesToFiles();
    playGame(0);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
struct stat st={0};
const char*房间名称[]={“水”、“火”、“风”、“土”、“等离子体”、“暗物质”、“空气”、“冰”、“岩石”、“熔岩”};
int i,j;
char目录[20];
字符*房间[7];
int连接[7][7]={0};
整数=0;
char roomChoice[20];
char*movesRecord[100];
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
void getRoomChoice(){
fflush(stdin);
scanf(“%s”,roomChoice);
fflush(stdin);
fflush(stdout);
}
void*getTime(void*arg){
pthread_mutex_lock(&mutex);
FILE*FILE=fopen(“currentTime.txt”,“w”);
时间短了;
结构tm*定位时间;
curtime=时间(空);
loc_时间=本地时间(&curtime);
fprintf(文件,“%s\n”,asctime(loc_time));
fclose(文件);
pthread_mutex_unlock(&mutex);
}
void*createRooms(){
//创建目录
int pid=getpid();
字符前缀[]=“eldridgt.”;
sprintf(目录,“%s%d”,前缀,pid);
if(stat(directory,&st)=-1){
mkdir(目录,0700);
}
//从0-6获取随机非重复数组
int随机数组[10];
int x,p;
整数计数;
int i=0;
srand(time(NULL));//随机种子

对于(count=0;count您的C教科书或教程应该解释如何使用
extern
变量在不同的源文件之间共享变量。使用全局变量非常简单,因为您所要做的就是在其他文件中将它们声明为
extern
。但我并不建议使用全局变量。另外,使用
f在仅输入的流中刷新(如stdin
)确实是未定义的行为。如果您希望可移植,请不要这样做。请尝试重新编码您的应用程序,这样它就不需要在文件之间共享全局变量,而是将所有内容作为函数参数和返回值进行传递。如果您需要帮助以使
extern
方法起作用,请显示您的最佳尝试,但该尝试不起作用因此,我们可以指出确切的问题。但如果可以,最好避免使用全局变量。