0

I try to read all the strings from the file "Text.txt" and add the strings to a vector by using this code:

std::ifstream in;
in.open("Text.txt");
std::vector<std::string> vec;
while (!in.eof()) {
  in >> str;
  vec.push_back(str);
}

The problem is that I read the last string twice. Any idea why this is happening? Thank you!

Wyck
  • 10,311
  • 6
  • 39
  • 60
Abacus
  • 1
  • 1
  • 1
    Does this answer your question? [read word by word from file in C++](https://stackoverflow.com/questions/20372661/read-word-by-word-from-file-in-c) – Wyck Aug 11 '20 at 15:06
  • Unfortunately, this does not answer my problem. I am aware of this solution, but I cannot use it because of some specifics of my problem. – Abacus Aug 11 '20 at 16:36
  • Care to be more specific? It literally explains your exact problem in all the detail you've provided. tldr: Don't use `.eof()` use `while(in >> str)`. What is different about the specifics of your problem? Please divulge the details. – Wyck Aug 11 '20 at 16:39
  • Thank you Wick, I finally solved my problem by using while(in >>str). Still, I don't understand the behavior when using while (!in.eof()), why is the last string read twice. – Abacus Aug 13 '20 at 05:49

1 Answers1

0

It's explained elsewhere on this site already.

In this order:

  1. in.eof() checks eofbit which is false. No read operation has read the end of file yet. The loop continues.
  2. in >> str encounters the end of file and sets eofbit. This also leaves str unchanged from the last iteration,
  3. you push the old (unchanged) str which is now in your vector twice,
  4. you exit the loop when in.eof() checks eofbit.

Your misunderstanding is that in.eofis doing something to detect the end of file condition -- but, it's not. It just checks eofbit. eofbit isn't set until the >> operation is performed.

Carefully read documentation for ios::eof, which I shall excerpt here:

std::ios::eof

Returns true if the eofbit error state flag is set for the stream.

This flag is set by all standard input operations when the End-of-File is reached in the sequence associated with the stream.

Note that the value returned by this function depends on the last operation performed on the stream (and not on the next).

To fix the problem

in >> str will return whether or not a string was read. Just base your loop condition on that.

while(in >> str)
   vec.push_back(str);
Wyck
  • 10,311
  • 6
  • 39
  • 60