fstream reaching eof prematurely

Started by
1 comment, last by snk_kid 19 years, 3 months ago
I'm having an interesting error while trying to load a milkshape model using fstream. Essentially the stream seems to reach the end of file marker long before the actual end of the file. Reading the file length at the beginning with

fin.seekg(0, std::fstream::end);
std::clog<<"FileLength: "<<fin.tellg()<<std::endl;
fin.seekg(0,std::fstream::beg);

gives 6434 - the correct length for the file however during triangle loading (in a loop for testing purposes - previously it was loading just as a single block - same problem just harder to pinpoint) I have

for(int i=0; i<nNumTriangles; i++)
{
	fin.read((char*)&(tTriangles), sizeof(ms3d_triangle_t));
	std::clog<<fin.tellg()<<'\t';
	std::clog<<fin.eof()<<std::endl;
}

looking at (a portion) the log file gives 2584 0 2654 0 2724 0 -1 1 -1 1 -1 1 -1 1 -1 1 since the ms3d_triangle_t structure is indeed 70 bytes it appears that everything is working normally - and then it abruptly reaches the EOF, except at offset 2724 rather than 6434. Does anyone know what might be causing this problem or have any suggestions for tracking it down. I've already hand parsed this section of the file to make sure it lines up with what I expect - and it does. Thanks. edit: its [ source ] not
Advertisement
I'm not too familiar with the C++ file handling classes, but is the file opened in binary mode? One of the typical problems with reading binary files in text mode is that you find data that matches an EOF in the middle of the file.
Harry.
First of all std::basic_istream::tellg reports the current position of the get pointer (current read position in the stream) which refers to a stream buffer what you want is std::basic_istream::gcount which returns the number of characters read during the last unformatted input (there not the same), basically how many bytes read from last unformatted I/O op.

The number -1 that std::basic_istream::tellg returns is indicating that I/O has failed & the failbit has been set, you should check the state of the stream after each I/O operation or turn exceptions on for a stream. I can not say i'm 100% sure of why your getting the problem but i have some suggestions:

A: Opened the stream in text mode.
B: Incorrectly read the variable nNumTriangles from file.
C: Alignment and padding by the compiler is messing you up, you want to make sure you have one byte alignment, you can force the compiler to align this is different for every compiler so check documentation.

i also sugggest that you read in all ms3d_triangle_t in one go:

std::vector<ms3d_triangle_t> tris;//....tris.reserve(nNumTriangles);if(!fin.read(reinterpret_cast<char*>(&tris[0]), sizeof(ms3d_triangle_t) * nNumTriangles)) {   //do error handling}


[Edited by - snk_kid on January 17, 2005 4:22:07 AM]

This topic is closed to new replies.

Advertisement