There are two my doubts about the behavior of fscanf and I will summarize them in the following two cases.
CASE 1
Imagine that you have the text file example.txt with the following content: 12.3 13.4 14.5 5.5
Given the following code :
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *f; float ft;
f = fopen(argv[1],"r");
while(!feof(f)){
fscanf(f,"%f",&ft);
printf("%f\n", ft);
}
return 0;
}
We execute the command "./program example.txt".
Why does the output always repeat the last number twice ? Shouldn't the pointer f have been advanced to the end of the file after the first read of 5.5 and exited the loop afterwards?
CASE 2
Let's assume exactly the same situation , but the content of example.txt is now the following: 12.3 13.4 14.5 hello 5.5
Why does it print in an infinite loop 14.5 ? When encountering an unexpected structure (because it expects a float, not a String), why does it react like this?
Thanks, this is it.
feof()
is not True until a read operation has occurred that has found the end of the file.fscanf()
has read 5.5 successfully, so it does not report end of file. The nextfscanf()
one will no longer be able to read another float, since it will find the end of the file and will return an error (in this case it is not modifiedft
, which is still worth 5.5 from the previous iteration). Thenfeof()
it will already be True and the loop will end.In the second case, when "hello" is found, it
fscanf()
will return an error again and leave the variable untouchedft
. Due to the error, the file reading pointer does not advance either, so in the next iteration it will be in the same position, it will produce an error again, etc...Your error is in not verifying if
fscanf()
it is returning an error or not. You must verify this by collecting the return value, which is the number of items correctly read and stored byfscanf()
. It should be greater than zero.Now on an error we write an error message, and exit the loop.