Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从文本文件读取行到结构C_C_List_File_Text_Struct - Fatal编程技术网

从文本文件读取行到结构C

从文本文件读取行到结构C,c,list,file,text,struct,C,List,File,Text,Struct,我正在尝试从列表中读取行到我的结构,它几乎可以工作了。我不确定问题出在哪里,但当我调用structs时,文本文件的最后一行不会出现,我认为单词的位置不对 void loadFile(char fileName[], Song *arr, int nrOf) { FILE *input = fopen(fileName, "r"); if (input == NULL) { printf("Error, the file could not load!");

我正在尝试从列表中读取行到我的结构,它几乎可以工作了。我不确定问题出在哪里,但当我调用structs时,文本文件的最后一行不会出现,我认为单词的位置不对

void loadFile(char fileName[], Song *arr, int nrOf) {

    FILE *input = fopen(fileName, "r");


    if (input == NULL) {
        printf("Error, the file could not load!");
    } else {

        fscanf(input, "%d", &nrOf);
        fscanf(input, "%*[^\n]\n", NULL);

        for (int i = 0; i < nrOf; i++) {
            fgets(arr[i].song, sizeof(arr[i].song), input);
            fgets(arr[i].artist, sizeof(arr[i].artist), input);
            fgets(arr[i].year, sizeof(arr[i].year), input);
        }
        for (int i = 0; i < nrOf; i++) {
            printf("%s", arr[i].song);
            printf("%s", arr[i].artist);
            printf("%s", arr[i].year);
        }
        rewind(input);
        printf("The file is now ready.\n");

    }

    fclose(input);

}
能够在nrOf获得号码后跳过第一行

编辑: 以下是结构:

typedef struct Song {

char song[20];
char artist[20];
char year[5];

} Song;
以下是文本文件:

4
Mr Tambourine Man
Bob Dylan
1965
Dead Ringer for Love
Meat Loaf
1981
Euphoria
Loreen
2012
Love Me Now
John Legend
2016
结构是动态分配的:

Song *arr;
arr = malloc(sizeof(Song));

最后一行不打印的原因有多种

主要原因是最后一行从未被读取

不应在文件无法打开的任何执行路径中调用
fclose()

当下一条语句是
fclose()

由于对
Song
数组中字段的
printf()
的调用被一个接一个地输出,这将导致向终端输出很长的单行,希望终端设置为在输出如此多的列后自动滚动,但这不能依赖于此

输出错误消息时,最好将其输出到
stderr
,而不是
stdout
。函数:
peror()
执行此操作,并输出操作系统认为错误发生的原因。(它通过引用
errno
选择要输出的错误消息来执行此操作。)

以下是关键问题:

如果输入文件每行包含一首歌曲信息,则字段
year
将包含尾随的换行符,或者换行符未被读取。如果未读取换行符,则下一次尝试输入歌曲标题的对
fgets()
的调用将只接收换行符,然后(所有歌曲的)所有后续字段将逐渐远离

建议在读取歌曲字段后,使用循环清除输入行中的所有剩余字符,类似于:

int ch;
while( (ch = getchar( input )) && EOF != ch && '\n' != ch );

如果您要包含一个小的文本摘录或您正在读取的文件的示例,那么它可能会很有用。这将使我们(其他SO用户)有机会了解您正在使用的具体内容,以便我们能够更好地为您提供建议。了解
歌曲的定义可能会有所帮助。如果您想阅读行,请阅读行(fgets对此没有问题),然后将它们解析为字符串(sscanf、strtok、plain for loop char by char…。此外,总是检查scanf函数的返回值。@hyde和
fgets
,OP甚至不检查错误。
int ch;
while( (ch = getchar( input )) && EOF != ch && '\n' != ch );