buzzzen
buzzzen

Reputation: 81

Can `scanf("%*s")` fail?

I want to write a C program counting the words of a text file. I use the loop below:

while (fscanf(fp, "%*s") != EOF ) {
    count++;
}

fp points to a text file. Is it possible that this fscanf() function have an early matching failure? Because I think it will definitely reach the end of the file, so the != EOF.

Upvotes: 4

Views: 181

Answers (1)

chqrlie
chqrlie

Reputation: 144949

Your program should work as expected as fscanf(fp, "%*s") returns 0 except for input failures where it returns EOF. Unless you make the input stream wide oriented and there is an encoding error, input failures should only occur for end of file and read errors.

fscanf(fp, "%*s") never returns 1 because the * causes the input match to be ignored in the return value, only the assigned converted values are counted:

7.21.6.2 The fscanf function

...

Returns

The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.

This can be verified with this program:

#include <stdio.h>

int main() {
    int res = scanf("%*s");
    printf("scanf(\"%%*s\") -> %d\n", res);
    return 0;
}
chqrlie$ ./scanf0 < /dev/null
scanf("%*s") -> -1
chqrlie$ echo 'test' | ./scanf0
scanf("%*s") -> 0

For your purpose, you might write this alternative which emphasizes the expected return value:

while (fscanf(fp, "%*s") == 0) {
    count++;
}

Upvotes: 3

Related Questions