eof() bad practice? [duplicate]

Possible Duplicate:
Why is iostream::eof inside a loop condition considered wrong?

So I've been using the eof() function in a lot of my programs that require file input, and my professor said that it is fine to use but a few people on SO have said that I shouldn't use it without really specifying the reason. So I was wondering, is there a good reason?


Solution 1:

You can use eof to test for the exact condition it reports - whether you have attempted to read past end of file. You cannot use it to test whether there's more input to read, or whether reading succeeded, which are more common tests.

Wrong:

while (!cin.eof()) {
  cin >> foo;
}

Correct:

if (!(cin >> foo)) {
  if (cin.eof()) {
    cout << "read failed due to EOF\n";
  } else {
    cout << "read failed due to something other than EOF\n";
  }
}

Solution 2:

You shouldn't use it because if input fails for another reason, you can be screwed.

while(!file.eof()) {
    int i;
    file >> i;
    doSomething(i);
}

What happens in the above loop if the contents of file are "WHAARRRRRRGARBL"? It loops infinitely, because it's not the end of the file, but you still can't extract an int from it.

Solution 3:

How are you using it? What .eof() will tell you is that the stream has already hit the end of file, that it has tried to read data that isn't there.

This isn't usually what you want. Usually, you want to know that you are hitting the end of file, or that you are about to hit the end of file, and not that you have already hit it. In a loop like:

while(!f.eof())
{
    f >> /* something */;
    /* do stuff */
}

you are going to attempt to read input in and fail, and then you are going to execute everything in /* do stuff */, and then the loop condition fails and the loop stops.

Another problem with that loop is that there's other ways input can fail. If there's an error condition on the file that isn't EOF, .fail() will return true but .eof() won't.