简体   繁体   English

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

[英]Reading lines from text file to structs C

I am trying to read lines from a list to my structs, and it is almost working.我正在尝试将列表中的行读取到我的结构中,并且几乎可以正常工作。 I am not really sure what the problem is, but the last line of the text file wont show up when I call for the structs and I do not think the words are placed right...我不太确定问题是什么,但是当我调用结构时,文本文件的最后一行不会出现,而且我认为这些词的位置不正确......

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);

}

The text file starts with a number on the first line to keep track of how many songs there are in the list.文本文件以第一行的数字开头,用于跟踪列表中有多少首歌曲。 I therefore tried with this:因此,我尝试这样做:

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

to be able to skip the first line after nrOf got the number.能够在 nrOf 获得数字后跳过第一行。

EDIT: Here is the struct:编辑:这是结构:

typedef struct Song {

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

} Song;

Here is the text file:这是文本文件:

4
Mr Tambourine Man
Bob Dylan
1965
Dead Ringer for Love
Meat Loaf
1981
Euphoria
Loreen
2012
Love Me Now
John Legend
2016

And the struct is dynamic allocated:并且结构是动态分配的:

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

there are a combination of reasons why the last line(s) do not print最后一行不打印的原因有多种

The main reason is the last line(s) were never read主要原因是从未读过最后一行

Should not call fclose() in any execution path where the file failed to open不应在文件打开失败的任何执行路径中调用fclose()

there is no need to call rewind() when the next statement is fclose()下一个语句是fclose()时不需要调用rewind() fclose()

Since the calls to printf() for the fields in the Song array are output, one right after another, this will result in a long long single line output to the terminal, Hopefully the terminal is set to automatically scroll after so many columns of output, but that cannot be depended upon.由于对Song数组中的字段调用printf()是一个接一个的输出,这会导致输出到终端很长很长的单行,希望终端设置为在输出这么多列后自动滚动,但这不能依赖。

When outputting an error message, it is best to output it to stderr , not stdout .输出错误消息时,最好将其输出到stderr ,而不是stdout The function: perror() does that AND also outputs the reason the OS thinks the error occurred.函数: perror()这样做并且还输出操作系统认为发生错误的原因。 (it does this by referencing errno to select which error message to output.) (它通过引用errno来选择要输出的错误消息来做到这一点。)

the following is the key problem:以下是关键问题:

if the input file contains one song info per line then the field year will either contain a trailing newline or the newline will not have been read.如果输入文件每行包含一个歌曲信息,则字段year将包含一个尾随换行符,或者该换行符将不会被读取。 If the newline was not read, then the next call to fgets() which was trying to input the song title will only receive a newline then all following fields (of all songs) will be progressively further off.如果没有读取换行符,那么下一次尝试输入歌曲标题的fgets()调用只会收到一个换行符,然后所有后续字段(所有歌曲的)将逐渐远离。

Suggest after reading a song fields, use a loop to clear out any remaining characters in the input line, similar to:建议在读完一个歌曲字段后,使用循环清除输入行中的任何剩余字符,类似于:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM