这非常奇怪 - 我从文件中获取行,将它们打印到屏幕上,然后将它们存储在数组中。当它们打印到屏幕上时,一切看起来都很好,但在数组中,每个元素都设置为文件的最后一行。
文件如下所示:
DarkMatter
Fire
Water
Air
Earth
Plasma
Wind
这是我的代码:
char *rooms[7];
FILE *roomFile = fopen("rooms.txt", "r");
char name[20];
for(i=0; i<7; i++) {
fgets(name, sizeof name, roomFile);
rooms[i] = name;
printf("%s", rooms[i]);
}
for(i=0; i<7; i++) {
printf("%s\n", rooms[i]);
}
在文件循环期间打印rooms[i]
时,一切看起来都很好,但是一旦我尝试打印房间数组后,每个元素都设置为wind
。这怎么可能呢?
输出:
DarkMatter
Fire
Water
Air
Earth
Plasma
Wind
Wind
Wind
Wind
Wind
Wind
Wind
Wind
答案 0 :(得分:0)
替换
rooms[i] = name;
与
//rooms[i] = name;
rooms[i] = malloc(20);
strcpy(rooms[i], name);
<强>原因强>
语句rooms[i] = name;
只是指示指针rooms[i]
等于指针(或数组)name
。因此,rooms[0], rooms[1], rooms[2]
中的每一个都有效地保存name
的地址。在for
循环的每次迭代中,name
都会被另一个字符串复制。但name
指出的地址因此rooms
的所有要素保持不变。
答案 1 :(得分:0)
这里有几个问题需要解决。您已将rooms
声明为指向char
的指针数组,但后来将其视为二维数组。您可以malloc
空间来存储字符串,但简单地将rooms
声明为二维数组更简单。
打开文件时,应始终检查以确保文件已成功打开。如果选择分配内存,则应同样检查分配错误。您还应检查fgets()
返回的错误值。
在第一个循环中,将缓冲区name
的内容分配给rooms[i]
,这是一个指针。但是你无法在C中以这种方式分配数组。如果你将rooms
的声明更改为:
char rooms[7][20]
然后您可以使用strcpy()
将name
的内容复制到rooms[i]
。或者,您可以使用strdup()
复制缓冲区的内容。这样做的好处是strdup()
为您分配存储空间,但您仍然必须记住以后释放存储空间。您也可以自己分配内存,并将name
的内容复制到分配的区域。
以下是代码的修改版本,使用最简单的方法,即将rooms
简单地声明为二维数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char rooms[7][20];
FILE *roomFile = fopen("rooms.txt", "r");
if (roomFile == NULL) { // error checking
fprintf(stderr, "Error opening file\n");
exit(EXIT_FAILURE);
}
char name[20];
for(size_t i = 0; i < 7; i++) {
fgets(name, sizeof name, roomFile);
strcpy(rooms[i], name);
printf("%s", rooms[i]);
}
for(size_t i = 0; i < 7; i++) {
printf("%s\n", rooms[i]);
}
return 0;
}