Reputation: 28178
The following causes a bug because file.eof()
apparently doesn't return true
until a read past the end of the file. How should I be doing this?
std::ifstream file("something.stuff", std::ios::in|std::ios::binary);
while(!file.eof())
{
double x, y, z;
file.read(reinterpret_cast<char*>(&x), sizeof(x)); // Do I need to check if(file) after every read?
file.read(reinterpret_cast<char*>(&y), sizeof(y));
file.read(reinterpret_cast<char*>(&z), sizeof(z));
// Do something with xyz
}
Upvotes: 2
Views: 3990
Reputation: 5042
Yes, the end of stream could be reached during each read, so you should check if each one succeeds before proceeding
std::ifstream file("something.stuff", std::ios::in|std::ios::binary);
while(!file.eof())
{
double x, y, z;
if (!file.read(reinterpret_cast<char*>(&x), sizeof(x)) ||
!file.read(reinterpret_cast<char*>(&y), sizeof(y)) ||
!file.read(reinterpret_cast<char*>(&z), sizeof(z)))
{
// failure... perhaps check file.eof() and/or file.fail() for precise condition
break;
}
else
{
// Do something with xyz
}
}
Upvotes: 1
Reputation: 103693
You can just check it after all the reads, unless you intend to do something with partial data, so:
while(true)
{
double x, y, z;
file.read(reinterpret_cast<char*>(&x), sizeof(x));
file.read(reinterpret_cast<char*>(&y), sizeof(y));
file.read(reinterpret_cast<char*>(&z), sizeof(z));
if (!file)
break;
// Do something with xyz
}
Upvotes: 9
Reputation: 7959
Alternatively, find the length of the file upfront using seek and tell, and then calculate how many iterations you should perform. That way you don't have to keep checking the eof bit after every read.
Upvotes: 1
Reputation: 33392
std::ifstream::read
should set the eof
flag once you read past the end of the file.
So, yes, you should just check file.eof()
after each call to file.read()
.
Upvotes: 1