David
David

Reputation: 28178

What condition should I use to stop a file reading loop?

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

Answers (4)

Monroe Thomas
Monroe Thomas

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

Benjamin Lindley
Benjamin Lindley

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

MikeP
MikeP

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

houbysoft
houbysoft

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

Related Questions