Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for fscanf to return zero and consume input at the same time?

Tags:

c

scanf

Is it possible for fscanf to consume input and return zero at the same time? For example, if I write

int res;
int k = fscanf(f, "%d", &res);

and check that k == 0, can I be sure that the next invocation of fscanf on the same file f would continue at the same spot where the file was prior to the invocation of fscanf?

like image 817
Sergey Kalinichenko Avatar asked Jan 29 '23 00:01

Sergey Kalinichenko


1 Answers

Another variant on the theme outlined in dasblinkenlight's answer is:

for (int i = 0; i < 20; i++)
{
    int rc;
    int number;
    if ((rc = scanf(" this is the time for all good men (all %d of them)", &number)) == 0)
    {
        char remnant[4096];
        if (fgets(remnant, sizeof(remnant), stdin) == 0)
            printf("Puzzling — can't happen, but did!\n");
        else
        {
            printf("The input did not match what was expected.\n");
            printf("Stopped reading at: [%s]\n", remnant);
        }
    }
    else if (rc == 1)
        printf("%d: There are %d men!\n", i + 1, number);
    else
    {
        printf("Got EOF\n");
        break;
    }
}

Try it on a file containing:

this is the time for all good men (all 3 of them)
this is the time for all good men (all 33 men)
   this   is   the
      time      for

all     good      men
(all

333 of

     them)
       this is the time for all good men to come to the aid of the party!

Etc.

Output:

1: There are 3 men!
2: There are 33 men!
The input did not match what was expected.
Stopped reading at: [men)
]
4: There are 333 men!
The input did not match what was expected.
Stopped reading at: [to come to the aid of the party!
]
Got EOF

Note that the conversion succeeded on the second sentence, even though the matching failed on 'men)' (where 'of them)' was expected). There is no reliable way to get information about matching failures after the last counted (non-suppressed, non-%n) conversion. The next attempt to match failed altogether, but the fgets() cleaned up the input (read the residue of the line), and then the subsequent attempt succeeded, because the blanks in the format string match arbitrary sequences of white space in the input. In the last line of the example data, the information 'this is the time for all good men' was read successfully, but 'to come to the aid of the party' did not match.

like image 110
Jonathan Leffler Avatar answered Feb 07 '23 18:02

Jonathan Leffler