简体   繁体   中英

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.

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

there is no need to call rewind() when the next statement is 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.

When outputting an error message, it is best to output it to stderr , not stdout . The function: perror() does that AND also outputs the reason the OS thinks the error occurred. (it does this by referencing errno to select which error message to output.)

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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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