当两个程序都需要某些变量时,将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
方法起作用,请显示您的最佳尝试,但该尝试不起作用因此,我们可以指出确切的问题。但如果可以,最好避免使用全局变量。