Every solution so far presented has a good explanation of why the OP code is wrong. But most have the incorrect solution to the problem.
As stated many times before the EOF flag is not set until you try and read past the end of file. The last successful read may read up-to (inclusive) the last character. So in your case the last read will read the 5 from the file and then print it. We then renter enter the loop (which will work because the last read did not read past the end of file and thus EOF is false). Your attempt to read the next character will fail at f >> x
and the variable 'x' will be left untouched (in your code this means it has the last value read a 5) and is then printed.
The solution is to test the condition of the stream after you have done the read to make sure it works. Note: You should not exclusively test for EOF there are other bad states. If one of the other bad states is entered the current code will enter an infinite loop. To check for all bad bits call fail() on the object. So the easiest solution is to put the read into the while test ( see below )
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
int x;
ifstream f;
f.open("note");
while(f>>x)
{
cout<<x<<endl;
}
return 0;
}
This works because the >> operator returns a stream. When a stream object is used in a boolean context it is converted into a type than can represent true/false (for technical reasons this is not bool but you can think of it as a bool). The value returned depends on the state of the stream. If the stream is in a good state then it will (in a boolean context) evaluate to true thus allowing the loop to be entered, if the stream object is in an invalid state (ie EOF (or other failed state) is true) then it will evaluate to false and the loop is not entered.
Note: The conversion actually calls fail() on the stream to test the state.
If your code is complex and you can not test the state as part of the read. Then after each read you MUST test the state of the object to verify it worked.
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
int x;
ifstream f;
f.open("note");
while(f)
{
f>>x;
if (f) // dont' use f.eof() there are other bad states.
{ // This will actuall call f.fail() which test for all bad states.
// Thus it only prints if the read worked.
cout<<x<<endl;
}
// Alternatively you can put the read into the if
if ( f >> x)
{
// STUFF
}
}
return 0;
}
In response to Jim's comments.
Once a number has been read from the stream with the >> operator. No other characters are read. TO show this is true try the following code:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream file("txt");
std::string line;
int x;
while(f >> x)
{
std::getline(f, line); // If the '\n' was read then
// this code would remove the next line.
// As it works correctly it simply removes then
// characters upto the newline character after the number.
std::cout << x << "\n";
}
}