3

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


I've got very simple question...

#include<iostream>
using namespace std;
int main()
{
    char x;
    while(!cin.eof())
    {
        cin>>x;
        cout<<"char: "<< x << endl;
    }
    return 0;
}


Why when i try to run this code on Linux:
./file_name < test_file.txt
The result is:
char: a
char: b
char: c
char: d
char: d
when test_file.txt is only:
abcd

Community
  • 1
  • 1
rAge
  • 65
  • 2
  • 2
  • 5
  • 2
    See [Why is iostream::eof inside a loop condition considered wrong?](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – R. Martinho Fernandes Nov 12 '12 at 12:52
  • Because it's always wrong, wrong, wrong to use `eof()` at all. There are thousands of duplicates of this by now, and if a question isn't a duplicate, it still contains the same error... grumble grumble – Kerrek SB Nov 12 '12 at 12:59

3 Answers3

10

End of file is detected by failing an input operation.

So, in

    cin>>x;
    cout<<"char: "<< x << endl;

the output statement is executed even when the input operation fails.

And when it fails, it doesn't update x.

Instead of testing .eof(), test .fail().

You can do that by using the stream object directly as a condition, e.g.

#include<iostream>
using namespace std;
int main()
{
    char x;
    while( cin >> x )
    {
        cout<<"char: "<< x << endl;
    }
}

Here the expression cin >> x performs an input operation that might update x, and as its expression result returns a reference to the stream, i.e. to cin. So cin is being used directly as a condition. That invokes a conversion to boolean, which is defined such that it on its own is equivalent to !cin.fail() (i.e., the expression cin >> x as condition is equivalent to writing !(cin >> x).fail() or, as a comma expression, (cin >> x, !cin.fail())).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

You are using a slightly wrong pattern to read from the file. The correct form is

while(cin >> x) {
    cout<<"char: "<< x << endl;
}

Keep in mind that eof tells you if you have attempted to read past the end of input; it does not tell you if you are just about to do so. Your original code reads the d for the first time, sees that it hasn't attempted to read off the end, then tries to read once more. This read fails, but you are now inside the loop and x has the value d from the previous iteration, so it's printed once more.

The code above tests the state of the stream (which incidentally will not only catch end-of-file but also errors) after it has attempted to read into x; therefore the loop will not be executed at all after the first read that fails.

Jon
  • 428,835
  • 81
  • 738
  • 806
-1

you must use for loop with file size to avoid null char

user1816090
  • 13
  • 1
  • 3