逐行读取文件只返回最后一行

时间:2017-02-11 01:10:11

标签: c arrays file

这非常奇怪 - 我从文件中获取行,将它们打印到屏幕上,然后将它们存储在数组中。当它们打印到屏幕上时,一切看起来都很好,但在数组中,每个元素都设置为文件的最后一行。

文件如下所示:

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

2 个答案:

答案 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;
}
相关问题