简体   繁体   中英

Why my code cannot stop? use fscanf

I want to continue read file until it ends,but it ouputs error answer and cannot stop. my code is:

    #include <stdio.h>
    #include <stdlib.h>

    void create() {
        FILE *fin = fopen("in", "r");
        int temp[4], t;
        int aaa;

        while ((aaa = scanf(fin, "%d:%d:%d:%d/%d", 
                      &temp[0], &temp[1], &temp[2], &temp[3], t)) != EOF) {
            printf("%d\n", aaa);
            printf("%d:%d:%d:%d\n", temp[0], temp[1], temp[2], temp[3]);
        }

        fclose(fin);
    }

    int main() {
        create();

        return 0;
    }

and my input file content is:

103.29.43.0/24
103.29.5.0/24
103.29.52.0/22
103.29.56.0/22
103.29.60.0/22
103.2.96.0/22
103.29.64.0/24
103.29.65.0/24
103.29.66.0/24
103.29.67.0/24
103.29.7.0/24

but it outputs:

0
103:0:0:0
0
103:0:0:0
0
103:0:0:0
....(loop)
  1. Your fscanf should have . instead of : between %d as that's causing mismatch.
  2. Also use &t instead of t . See man fscanf
  3. Also while(fscanf() != EOF) mean even if any matching failure occurs and fscanf fails to match and store all 5 arguments (which is happening here due to : and . mismatch) then too continue the loop.
    You should use while(fscanf() == 5) to continue the loop only when all the 5 arguments of fscanf gets matched and stored.

There are several problems with your code:

  • you pass t instead of its address &t for the last format specifier, invoking undefined behavior.

  • The format string uses : instead of . as a separator, causing parsing failure.

  • fscanf returns the number of fields it parsed successfully. Only upon end of file and if no field could be parsed does it return EOF . Otherwise, if there is a character in the input stream that does not match the format, it stops and returns between 0 and 5 for your format string. For example, a . in the input stream will cause your while loop to go on for ever with fscanf returning 0 as the . does not match %d . This explains the current behavior you observe .

You should change the test to:

    while ((aaa = fscanf(fin, "%d.%d.%d.%d/%d",
                     &temp[0], &temp[1], &temp[2], &temp[3], &t)) == 5) {
        printf("%d\n", aaa);
        printf("%d:%d:%d:%d\n", temp[0], temp[1], temp[2], temp[3]);
    }

If you want to read from a FILE * handle, you need to use fscanf() instead of scanf() .

For example, with fin as the FILE * here:

while (fscanf(fin, "%d:%d:%d:%d/%d",
              &temp[0], &temp[1], &temp[2], &temp[3], &t) != EOF) { ... }

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