![]() |
||||
|
||||
|
« Things to Avoid in C/C++ -- fflush(stdin), Part 2 | Things to Avoid in C/C++ -- system("pause"), Part 4 » |
Things to Avoid in C/C++ -- feof(), Part 3
by: WaltP - Sep 20, 2005
feof() to exit a loopYou should never use feof() as the exit indicator for a loop. feof() is TRUE only after the end of file (EOF) is read, not when EOF is reached. To test this, create a normal text file (mine is feof.fil): Generic Code Example: 4 Walking 3 Working 2 Eating 1 Sleeping Then compile and run this code: C/CPP/C++ Code Example: #include <stdio.h> int main() { FILE *st; char buf[20]; st = fopen("feof.fil", "r"); if (st != NULL) { while (!feof(st)) { fgets(buf, 20, st); puts(buf); } fclose(st); } return 0; } You should see the following output: Generic Code Example: D:\C\GIDForum>feof 4 Walking 3 Working 2 Eating 1 Sleeping 1 Sleeping D:\C\GIDForum> What has happened is the last line of the file was read, but not the EOF. When the loop returns, the fgets() attempts to read one more record and failed. Since no error checking was done, whatever was left in the buffer is still there and the loop continues. Two ways pop into mind to solve this. Your read must test for an error. Fix 1A: C/CPP/C++ Code Example: while (!feof(st)) { if (fgets(buf, 20, st) != NULL) { // process your buffer puts(buf); } } fclose(st); Fix 1B: C/CPP/C++ Code Example: while (!feof(st)) { if (fgets(buf, 20, st) == NULL) { // exit the loop when done break; } } fclose(st); You'll notice a fair amount of code has been added to solve the problem, and you are now making TWO tests. One for feof() in the while, another for fgets() inside the loop. The preferred way (assuming your read is the first thing in the loop) is Fix 2: C/CPP/C++ Code Example: while (fgets(buf, 20, st) != NULL) { // process your buffer puts(buf); } fclose(st); Short and succinct.
|
GIDNetwork Sites
Archives
Recent GIDBlog Posts
Recent GIDForums Posts
Contact Us
|
« Things to Avoid in C/C++ -- fflush(stdin), Part 2 | Things to Avoid in C/C++ -- system("pause"), Part 4 » |