How do I scan a file in C using fscanf

2019-08-30 06:48发布

问题:

I am using the code

while(fscanf(input, "%49[^@ ]@%49s -> %49[^@ ]@%49s", sender, trash, receiver, trash) != EOF){
   printf("%s " "%s\n", sender, reciever);
}

to try to read and print every line from a file however when I run this code it gets stuck in an endless loop printing the first line of the file over and over again. How can I move the scanner down to the next line after it has executed this code. Thank you in advance for any help.

回答1:

#include < stdio.h >

FILE *fr;

main()
{
    int n;
    char line[80];

    fr = fopen ("test.txt", "r");  /* open the file for reading */

    while(fgets(line, 80, fr) != NULL)
    {
    /* get a line, up to 80 chars from fr.  done if NULL */
    sscanf  ( line );
    }
    fclose(fr);  /* close the file prior to exiting the routine */
}

The basic way to do what you want...



回答2:

  do {
        fscanf(input, "%49[^@ ]@%49s -> %49[^@ ]@%49s", sender, trash, receiver, trash);
        printf("%s " "%s\n", sender, reciever);
     } while(!feof(input));


回答3:

fscanf() returns number of conversions made. EOF is only returned when the very first conversion has failed. The proper way would be:

while (fscanf(fp, "...", &v1, &v2, ...) == <number_of_variables_read>) {
    ...
}

if (ferror(fp)) ...


回答4:

You should check return value from fscanf. This function returns number of succesful conversions, which may be less than number of conversions specified in format string.

In your case, it may mean that no conversions may have been performed in second call to fscanf, becaude of malformed data in file etc. As no data was read, file handle has not advanced, so end-of-file hasn't been reached, which in turn explains why loop does not terminate. As no data was read, previous values are printed in each loop iteration.



回答5:

Do not compare against EOF, compare against the expected number of parsed fields.

while(3 == fscanf(input, " %49[^@ ]@%*49s -> %49[^@ ]@%49s", sender, receiver, trash)){
   printf("%s " "%s\n", sender, receiver);
}

Some minor changes

Suspect you may want to skip over any leading whitespace, so begin format with " ". ( I am sure this is contributing to your end-less loop. First scanning leave the \n in the input queue. 2nd scan won't put \n into sender and fscanf() returns 0, which is not EOF. Vicious cycle repeats.)

No need to save your first scanning of trash field with `"%49s". Use "*" to scan and not save.

Scan the second trash field and save to add to the scan count. This helps validate the incoming data is formatted as expected. An alternate pedantic check could be " %49[^@ ]@%*49s -> %49[^@ ]@%*49s%[\n].

BTW, recommend using fgets() to get the line and use sscanf() to tear apart. Easier to handle I/O and parsing errors.



标签: c scanf