This link tells about why feof()
is a bad thing to use as an exit indicator for a loop.
Unsafe ==> having an feof()
check in the while, and an fgets()
inside the while.
Safe ==> having the fgets()!=NULL
check in the while itself.
I'm supposed to see the unsafe code doing an extra while loop iteration, but both do the same(and correct) number of loops. Can someone help me understand what's happening here ?
EDIT : The link actually did say why this is happening, but it took for the correct answer below for me to understand exactly what i was reading. My file did not have a '\n' at the last line, so got same results.
This is the file contents :
abcd
efgh
ijkl
And Here's code :
void testUnsafe(void) {
FILE *f;
char buf[20];
f = fopen("fil.txt", "r");
while (!feof(f)) {
fgets(buf, 20, f);
if (buf[strlen(buf) - 1] == '\n') //cleaner
buf[strlen(buf) - 1] = '\0';
printf("%s , %d\n", buf, strlen(buf));
}
fclose(f);
}
void testSafe(void) {
FILE *f;
char buf[20];
f = fopen("fil.txt", "r");
while (fgets(buf, 20, f) != NULL) {
if (buf[strlen(buf) - 1] == '\n') //cleaner
buf[strlen(buf) - 1] = '\0';
printf("%s , %d\n", buf, strlen(buf));
}
fclose(f);
}
Output is :
******unsafe test********
abcd , 4
efgh , 4
ijkl , 4
********safe test********
abcd , 4
efgh , 4
ijkl , 4
If your text file ends without a newline after the last line of text, the testUnsafe()
function will reach end-of-file when it reads the last line, and produce the three lines of output you have shown.
If your text file does have a newline after the last line of text, the function will read the last line, including the newline, without reaching end-of-file. When it enters the while()
loop again, it reads zero characters, sets the end-of-file flag, and outputs the last line which is still in the buffer from the last round.
The while (!feof(f))
construction is not unsafe in itself. It's neglecting to check the return value of fgets()
that is unsafe.