Using feof() and fread()

When reading single bytes from a file in C, one must pay attention to the correct usage of feof() and fread(). At first, the following piece of code seems to work correctly:

const char *filename = "hello";
unsigned char byte;
FILE *fp;
 
fp = fopen(filename, "rb");
 
if (!fp) {
    printf("could not open file\n");
    return 1;
}
 
while(!feof(fp)) {
    fread(&byte, 1, 1, fp);
    printf("%02x\n",byte);
}
 
fclose(fp);

Suppose the file “hello” has the following contents:

0000000: 68 65 6c 6c 6f 0a                                hello.

(which is the string “hello” followed by an LF)

When the code above is run, the following output is produced:

68
65
6c
6c
6f
0a
0a

Notice the last character seems to be read twice. The problem is that feof() only returns true after attempting to read past the end of the file. In order to fix this “read-twice” behavior, the return value of fread() must be checked:

if(!fread(&byte, 1, 1, fp)) {
    break;
}

Note: Using feof() as the while condition is kind of redundant here. In this situation, one could simply use while(1) and the behavior would be the same.

4 comments ↓

#1 Bryan Garber da Silva on 05.06.09 at 5:22 PM

Yep. I already had troubles with “feof()”. The key thing to remember is that you must use the while as if you were looping with an integer as the iterator like:

int i = 0;
while ( i < 9 ) {
printf(“%d”, i);
i = i + 1;
}

The difference is that you are iterating in a file stream:

unsigned char byte;
fread(&byte, 1, 1, fp);
while ( !feof(fp) ) {
printf(“%c”, byte);
fread(&byte, 1, 1, fp);
}

But, if you compare the two algorithms, you will see the same pattern.

#2 cesarbs on 05.07.09 at 12:22 AM

Haha, my post seems totally pointless now. I am going to update it and give you the credit for a much better solution 🙂

#3 Chandana on 01.17.11 at 1:35 PM

Actually your original solution is the better one. If fread fails for reasons other than eof, it will not go to an infinite loop

#4 snnn on 02.24.16 at 11:36 PM

You should always check the result value of fread/fclose/….

Leave a Comment