Why is fread reaching the EOF early?


Why is fread reaching the EOF early?



I am writing a C library that reads a file into memory. It skips the first 54 bytes of the file (header) and then reads the remainder as data. I use fseek to determine the length of the file, and then use fread to read in the file.

The loop runs once and then ends because the EOF is reached (no errors). At the end, bytesRead = 10624, ftell(stream) = 28726, and the buffer contains 28726 values. I expect fread to read 30,000 bytes and the file position to be 30054 when EOF is reached.

C is not my native language so I suspect I've got a dumb beginner mistake somewhere.

Code is as follows:

const size_t headerLen = 54;  FILE * stream; errno_t ferrno = fopen_s( &stream, filename.c_str(), "r" ); if(ferrno!=0) {   return -1; }  fseek( stream, 0L, SEEK_END ); size_t bytesTotal = (size_t)(ftell( stream )) - headerLen; //number of data bytes to read size_t bytesRead = 0; BYTE* localBuffer = new BYTE[bytesTotal]; fseek(stream,headerLen,SEEK_SET); while(!feof(stream) && !ferror(stream)) {     size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-bytesRead,stream);     bytesRead+=result; } 


Depending on the reference you use, it's quite apparent that adding a "b" to the mode flag is the answer. Seeking nominations for the bonehead-badge. :-)

This reference talks about it in the second paragraph, second sentence (though not in their table).

MSDN doesn't discuss the binary flag until halfway down the page.

OpenGroup mentions the existance of the "b" tag, but states that it "shall have no effect".




Why doesn't anyone upgrade their C compiler with advanced features?

1:



Crossplatform Bidirectional IPC
perhaps it's a binary mode issue.


Register allocation rules in code generated by major C/C++ compilers
Try opening the file with "r+b" as the mode..
Weird compile error dealing with Winnt.h
EDIT: as noted in a comment "rb" is likely a better match to your original intent since "r+b" will open it for read/write and "rb" is read-only..
New approach for adding a new Node to a Linked List


Function pointers in C - address operator “unnecessary”


How do I test at compile time the current version of GCC?

2:



What C/C++ compilers are available for VxWorks?
Also worth noting that simply including binmode.obj into your link command will do this for you for all file opens..


3:


A solution, based on the previous answers:.
    size_t bytesRead = 0;     BYTE* localBuffer = new BYTE[bytesTotal];     fseek(stream,headerLen,SEEK_SET);         while(!feof(stream) && !ferror(stream)) {         size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-         bytesRead,stream);     bytesRead+=result; } 



94 out of 100 based on 84 user ratings 934 reviews