Idiosyncracies of feof

Matthew Saltzman mjs at clemson.edu
Fri Dec 17 17:38:36 UTC 2010


On Thu, 2010-12-16 at 23:01 -0800, Shiraz Baig wrote:
> IdioSyncracies of feof()........
> I wrote the following code and wanted to read 16 bytes each time, in a loop.
> 
>   while (!feof(filein)) {
>       nbytes=fread(bufin, 1, 16, filein);
>       printf("Bytes Read = %d\n", nbytes);
>   }
>   
>   I noted that, if the "filein" size is exact multiple of 16 bytes, the
>   loop runs n times.  On the other hand if the "filein" size is not exact
>   multiple of 16 bytes, the loop runs n-1 times. That cost me 6 hours of
>   wasted time!
> 
>   I had a file of 84 bytes. While encrypting my loop ran 6 times. But
>   unfortunately, encrypted file has to be an exact multiple of 16 bytes,
>   ie it was 96 bytes. So, While decrypting, the the loop ran 7 times,
>   making me scratch my head for many hours. Because I wanted to write
>   same loop for both encrypting and decryption. I could not do so. Then
>   I had to put my own check, in addition to the feof() check.  what a
>   dumb function, this feof() is. It cannot distinguish that no bytes
>   are left and it should not run an extra time.  
> 
>   I also tried by putting fread() outside loop and at the end of loop,
>   but then my encrypting ran one times less :-(  So back to square one....
>   ie putting my own check in the code.
> 
>   Am I missing something?

feof() doesn't return nonzero until a short read is done (and only if
the read is short because the end of the file was encountered).  Thus,
for example, reading 16 bytes from a file of 16 bytes succeeds (so
feof() returns false) but the next read fails (and after that, feof()
returns true.  But a read of 16 bytes from a 15-byte file fails
(although the 15 bytes are copied), so feof() returns true after that.

If you always want ceil(filelength/16) iterations, the idiom you want
is:

        while ((nbytes = fread(bufin, 1, 16, filein)))
            printf("Bytes Read = %d\n", nbytes);
        
This repeats until a 0-byte read is performed.  nbytes will be positive
every time it's printed.  Now you can check to see why the read failed.
If feof(filein) is nonzero, then end-of-file was encountered.
Otherwise, if ferror(filein) is nonzero, then a read error was
encountered.

> 
> regards
> shiraz
> 
> 
> 
>       

-- 
                Matthew Saltzman

Clemson University Math Sciences
mjs AT clemson DOT edu
http://www.math.clemson.edu/~mjs




More information about the redhat-list mailing list