C++ File Handling Issue

Hello Guys,
I was trying file handling with C++. The problem that I encountered was that when I read from a file using << operator the last string was printed twice.


ifstream in("Sample.txt");
    if(!in)
    {
        cout<<"Unable to open file\n";
        return 1;
    }
    string str;   /* issue occurs here */
    while(in){
    in >> str;
    cout << str << endl;
    }
    in.close();
 

Suppose ‘Sample.txt’ file contains the string “Hello World” Then World is being printed twice. Now when I declare ‘string str’ inside the while loop it is giving correct o/p. So what could be the problem here?

I think that when the EOF is being reached it is not updating the string that is why when string is globally declared it is printing the old value.
Kindly Help!

if your file is

line 1
line 2

Then you are doing following:

  1. set str = line1, print str. If in.eof break.
  2. set str = line2, print str. If in.eof break.
  3. set in.eof, print str. If in.eof break.

You should rather do the following

string str;
while(in){
  in >> str;
  if( !in.eof() ) cout << str << endl;
}
in.close();

Or even better

string str;   / issue occurs here /
while(in >> str){
  cout << str << endl;
}

When you take str inside, it would be printing an empty string at end.

In first two iterations, the istream::operator>> function reads two strings Hello and World from the stream. The eof bit is set only when the istream::operator>> tries to read EOF. In beginning of third iteration, the eof is not yet set. The function tries to read EOF and, then eof is set. But content of variable str is not modified since istream::operator>> has read EOF from the stream. So str prints its previous content.

Following extract is given on cplusplus.com about istream::operator>>

Internally, the function accesses the input sequence by first
constructing a sentry object (with
noskipws set to false). Then (if
good)
, it extracts characters from its
associated stream buffer object as if
calling its member functions sbumpc or
sgetc, and finally destroys the sentry
object before returning.

ios::good function checks whether any of error state flag (eofbit, failbit and badbit) is set or not.

//