0

First semester C++ assignment and this is the one thing I'm having trouble with in it:

Basically there's this txt file that has three numbers on each line of it - the loop reads those into three variables and uses them to create an object and process with it. We had to do this using three different loop techniques. The first two were done using a counter based for loop and a sentinel value based while loop and were straight forward for me.

The last one though says "Write an end of file loop that reads an integer from fin into x in the conditional expression." (fin is the ifstream object)

Does something like this work?

while (fin >> x && !fin.eof())
{
rest of loop stuff
}

This just seems really odd to me to have something reading into a variable inside a loop's conditional expression. Wouldn't it make more sense to do something like this?

while (!fin.eof())
{
fin >> x;
rest of loop stuff
}

Thanks, appreciate any guidance!

  • 2
    Just do `while (fin >> x)`... If you do the first one (checking `eof()` in the loop condition), you might miss other errors (reading can fail for more reasons than just EOF). If you do the second one, you are only checking `eof()` (which isn't good enough, as I just said), plus you aren't checking whether the extraction succeeded or failed, which also isn't good. – Cornstalks Nov 17 '13 at 03:31
  • http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong –  Nov 17 '13 at 03:31

1 Answers1

3

You always want to check that your input was successful after you read the value! You normally don't want to use eof() to control an input loop: it is the wrong condition to check for.

For example, here is what goes wrong with the two code samples you posted:

  1. Your first loop (while (fin >> x && !fin.eof()))won't process the last value if it isn't followed by a newline. Although this rarely happens in files, it does happen frequently when reading from string streams (std::istringstream).
  2. Your second loop will probably process the last line twice: after reading the last value there is a good chance that the read stopped right on the last newline but before ever attempting to read beyond the file: eof() will be false, the read will fail, the value will be unchanged, and you process it twice.

The canonical input loop always looks basically like this:

while (in >> values) {
    <process-data-here>
}

There are a few variations how reading the values looks exactly, e.g., it can also use std::getline(in, line), but it always reads the value(s) and verifies that the stream isn't in failure state.

Dietmar Kühl
  • 141,209
  • 12
  • 196
  • 356
  • Thanks, I appreciate the info. This is really my fault for not taking better notes when he talked about this in class. I could have sworn he used fin.eof() for it though. – user3000818 Nov 17 '13 at 03:37
  • 1
    @user3000818 He probably did, it's a common mistake. – David Nov 17 '13 at 03:38
  • 1
    @user3000818: Too many books use this wrong approach. Especially the kind of books targeting people wanting (or needing) an easy start seem to be full of this sort of incorrect information. Oddly enough, these are also the books which seem to attract teachers the most. – Dietmar Kühl Nov 17 '13 at 03:56