0

I have a .txt file containing 6291456 numbers and nothing else. After reading all out and push_back into a vector, the vector.size() function returns 6291457. Where does this additional element come from?

    int disparity;
    ifstream disparity_txt;
    disparity_txt.open(path);
    while(!disparity_txt.eof())
    {
        disparity_txt >> disparity;
        vec_disparities.push_back(disparity);
    }
    cout << vec_disparities.size() << endl;
    disparity_txt.close();
quantdev
  • 22,595
  • 5
  • 47
  • 84
YuZ
  • 406
  • 5
  • 18
  • 1
    ...and don't use `endl` unless you *really* want a buffer flush (at a ~10:1 speed loss) along with writing a new-line character. – Jerry Coffin Aug 26 '14 at 15:44
  • 1
    If the stream by error contained non-numerical data, like ordinary text, you would get an infinite loop. Eventually crashing when exhausting memory. – user515430 Aug 26 '14 at 16:14

2 Answers2

5

Don't use while(!disparity_txt.eof()) it does not do what you think (eof will only be set after the end of the stream is read, so typically the last iteration is wrong) :

Do :

while(disparity_txt >> disparity)
{
    vec_disparities.push_back(disparity);
}
Community
  • 1
  • 1
quantdev
  • 22,595
  • 5
  • 47
  • 84
  • I tried this method but got 3145728, half the exact size returned. – YuZ Aug 26 '14 at 15:48
  • 1
    @user3921720 see my edit for the complete loop, you are doing a `disparity_txt >> disparity;` too much in the `while`. Hope this helps. – quantdev Aug 26 '14 at 15:51
2

Using while (!in.eof()) is almost always wrong

Either stop looping when extracting a number from the stream fails (as shown in quantdev's answer) or use the standard library facilities meant for populating a container from a stream:

std::ifstream disparity_txt(path);
vec_disparities.assign(std::istream_iterator<int>(disparity_txt),
                       std::istream_iterator<int>());

You can open an fstream using its constructor, and the destructor will close it, you don't need explicit open and close calls.

In C++11 it's even simpler:

vec_disparities.assign(std::istream_iterator<int>{std::ifstream{path}}, {});
Jonathan Wakely
  • 153,269
  • 21
  • 303
  • 482