Tuesday, 21 February 2017

c - feof() on Linux return true at one line later than the ending line




I'm a beginner of C. When I use this while loop to print the contains of a file. The last line will print twice on Linux. It should not get into while loop when reach the end of file. It has no problem on windows.



#include 
#include

int main()
{

char string[400];
FILE *file_para;

// Open the file
if ((file_para = fopen("Test.txt", "r")) == NULL)
{
printf("cannot open file\n");
getchar();
return 0;
}

while (!feof(file_para))
{
fgets(string, 400, file_para);
printf("**** %s", string);
}

fclose(file_para);
getchar();
return 0;
}

Answer



This is the wrong way to use feof(). Use feof() to detect what went wrong after one of the main I/O functions failed. It does not predict whether you're about to reach EOF; it tells you when some I/O function has already reported EOF. C is not Pascal; in Pascal, you can (must?) check for EOF before calling the I/O functions.



while (fgets(string, sizeof(string), file_para) != 0)
{
...do printing, etc...
}
// If you need to, use `feof()` and `ferror()` to sort out what went wrong.


If you really, really insist on using feof(), then you also need to check your I/O operation:



while (!feof(file_para))
{
if (fgets(string, sizeof(string), file_para) == 0)
break;
...do printing, etc...
}


Note that you might be failing because ferror(file_para) evaluates to true even when feof(file_para) does not...so maybe you need while (!feof(file_para) && !ferror(file_para)), but that really is just more evidence that the while loop should be conditioned on the I/O function, not feof().


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...