4

Why is it possible to read a file using a while loop such as

while (file >> variable)

Or

while (getline(xx, yy))

Do the >> and getline functions return boolean values ?

jww
  • 83,594
  • 69
  • 338
  • 732
mahela007
  • 1,299
  • 4
  • 18
  • 28
  • Also see [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/q/5605125/608639) – jww Feb 18 '18 at 10:49

3 Answers3

8

The stream operators evaluate to a reference to the stream itself. This allows chaining e.g. file >> variable >> variable >> variable.

When you combine it with the fact that the stream object is convertible to boolean (whose value is true iff no error flags are set) and, yes, you get that effect.

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
3

If we have something like:

a file with data:

11 
22 
13
45
19

and then a C++ file:

int variable;
int count = 0;
while(!file.eof())
{
    count ++;
    file >> variable;
}
cout << "there are  " << count << " numbers in the file";

the output from this would be 6, because when we read 19, eof is false, only when we try to read the NEXT number does eof get set. We could fix this by moving the count++ to an if-statement, so we have if (file >> variable) count++; instead. But that gets quite clumsy.

If we instead do:

while(file >> variable)
{
   count++;
}

the loop exits when when we try to read the next number after 19.

Edit: Fix "reason why it counts wrong" to clarify that eof() is set after "unsuccessful read".

Should also point out that the while(!file.eof()) doesn't work well with bad input. Say we have the above code, but the input is 11 22 aa ... - eof() doesn't get set when the input is aa. The input just stops and returns an error. But since eof() is still false [we can technically read more from the file, as long as we don't try to read it as a number]. So this leads to an infinite loop! The while (file >> variable) solution avoids this problem - of course, you may still need to add some extra code to say "I expected a number here, and I got something else". But you don't have to worry about the loop going on forever reading nothing.

Joel
  • 4,631
  • 9
  • 33
  • 51
Mats Petersson
  • 119,687
  • 13
  • 121
  • 204
  • The EOF being set "late" has nothing to do with extra newlines at the end of the file -- it's because `.eof` is set _after a read has failed_ due to EOF, not when the next would. Also you didn't answer the question. – Lightness Races in Orbit Dec 23 '12 at 12:02
  • Ah, ok. So let's get this right: If we have ... 19, it still won't set .eof() until the next attempt to read the ? Either way, using eof to determine end of file is bad, using "try to read and see if it failed" works much better. – Mats Petersson Dec 23 '12 at 12:06
  • Edited to cover the EOF situation better. – Mats Petersson Dec 23 '12 at 12:24
0

Sometimes they are made so for convenience; alternatively, they return a type which is castable to bool. You should refer to the documentation of these functions (or, stream operators).

Pavel Radzivilovsky
  • 17,994
  • 3
  • 54
  • 65