我正在制作C语言冒险游戏,这已经成为我存在的祸根。我正在努力并取得进展,但是,我遇到了一个我无法弄清楚的大问题。
这是交易:我需要创建7个文件,然后打印每个文件中每个房间的信息。
一个文件的示例是:
ROOM NAME: Chapel
CONNECTION 1: Arenas
CONNECTION 2: Pantry
CONNECTION 3: Forest
ROOM TYPE: START_ROOM
每个文件应具有不同的名称,不同的连接和不同的类型。但是,当我运行我的程序时,它会在每个文件中打印完全相同的内容。
我的程序很长,所以我不确定问题出在哪里,所以我只会写我创建文件的位置并调用函数写入它 - 如果你们需要看到更多让我知道。这也只是main和createRoom()函数的一部分。
int main() {
int buffer = 260;
int pid = getpid();
char *dirName = malloc(buffer);
char *prefix = "bonnc.rooms.";
snprintf(dirName, buffer, "%s%d", prefix, pid);
struct stat st = {0};
if (stat(dirName, &st) == -1) {
mkdir(dirName, 0777);
}
char rm1[260];
snprintf(rm1, 260, "%s/room1.txt", dirName);
roomFile1 = fopen(rm1, "w+");
createRoom(roomFile1, connections1, 1);
char rm2[260];
snprintf(rm2, 260, "%s/room2.txt", dirName);
roomFile2 = fopen(rm2, "w+");
createRoom(roomFile2, connections2, 2);
fclose(roomFile1);
fclose(roomFile2);
}
void createRoom(FILE *fp, char *conn[6], int roomNumber) {
srand(time(NULL));
int randName = rand() % 10;
int randType = rand() % 3;
int randConnections = rand() % (6 -2) +2;
int j = 0;
for (j = 0; j <= randConnections; j++) { //I do have additional code in here for testing of duplicates, but that isn't essential to the problem
randomRoom = rand () % 10;
conn[j] = names[randomRoom];
}
fprintf(fp, "ROOM NAME: %s\n", names[randName]); //names & randName are declared earlier
int t = 0;
for (t = 0; t <= randConnections; t++) { //randConnections defined earlier
fprintf(fp, "CONNECTION %d: %s\n", t+1, conn[t]; //conn[t] defined earlier
}
fprintf(fp, "ROOM TYPE: %s\n", types[randType]); //types & randType defined earlier
}
因此,当我使用room1和room2调用createRoom时,即使每次调用createRoom函数时都应生成新的随机名称,随机连接和随机类型,每个文件中都会打印完全相同的内容。
有什么想法吗?我是C的新手并且还在学习,所以如果有任何杂乱的代码我应该改变,请告诉我。谢谢!
更新:随机数不是全局的,它们位于createRoom()函数中。我添加了这段代码,以及连接的一部分[1]&amp;连接[2]已填充。希望这些信息有助于解决问题!
答案 0 :(得分:2)
void createRoom(FILE *fp, char *conn[6], int roomNumber) {
srand(time(NULL));
您不应多次拨打srand()
;这样做可以解除随机性。见srand()
— why call it only once?
除非你足够幸运,在一秒钟的垂死微秒中创建了房间1,并且在新的秒钟中创建了房间2,否则您使用相同的种子重新设置随机数生成器,因此每次生成相同的数字。
您似乎有一个全局变量randName
,它实际上是一个索引到一组名称的数字。您没有显示设置的位置,因此每次调用createRoom()
函数时,它可能都是相同的值,因此每次都会产生相同的输出。
还有一个全局变量randType
同样不会改变。并且connections1
中有一对数组connections2
和main()
,但是您没有显示设置它们的代码。
根据显示的上下文,您显然没有在调用createRoom()
函数之间更改这些变量的值,因此每次调用它时都会生成相同的输出。
哦,人们不喜欢全局变量是有原因的 - 这类问题就是其中之一。
对于凌乱的代码,除了已经列出的问题之外,使用malloc()
分配dirName
然后使用rm1
和{{1}的固定大小分配有点不一致}}。您也可以使用rm2
的固定大小。名义上,你应该检查缓冲区溢出,但260的大小似乎足够大,可用于显示的用途。
您应该始终检查dirName
是否成功。名义上,您应该检查写入是否成功,但该规则通常被忽略。你应该经常检查读取是否成功;这是一个永远不应该被打破的规则。
您应该始终检查内存分配调用是否成功。如果你不这样做,你的程序通常会崩溃,通常是在最不方便的时刻。如果你过度分配空间,你可能仍会遇到Linux等允许乐观内存分配的系统问题 - 即使fopen()
成功,你的进程也可能出现OOM杀手(内存不足)。