Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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".

like image 939
James Schek Avatar asked Oct 02 '08 19:10

James Schek


People also ask

What does fread return at EOF?

Return Value. The fread() function returns the number of full items successfully read, which can be less than count if an error occurs, or if the end-of-file is met before reaching count. If size or count is 0, the fread() function returns zero, and the contents of the array and the state of the stream remain unchanged ...

Does fread advance the file pointer?

Yes, calling fread does indeed move the file pointer. The file pointer will be advanced by the number of bytes actually read. In case of an error in fread, the file position after calling fread is unspecified.

What does fread do all day long?

The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.


1 Answers

perhaps it's a binary mode issue. Try opening the file with "r+b" as the mode.

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.

like image 122
Evan Teran Avatar answered Sep 29 '22 19:09

Evan Teran