Stream iterator reading std::cin misses 2nd and 3rd numbers

273 Views Asked by At
std::vector<int> v{};
std::istream_iterator<int> iter(std::cin), eof;

while (iter != eof) {
  v.push_back(*iter);
  ++iter;
}

When it executes, this program ignores the second and third integers entered into the standard input. For example, entering 1 2 3 4 5 ^Z and hitting enter results in a vector containing 1 4 5. The same thing happens when the input is separated by newline characters instead of spaces.

It's a simple example taken from C++ Primer (5th ed, p403) so I assume the fault lies with me. I've been stuck on this for a few hours so any help would be greatly appreciated.

EDIT: The code I originally posted was incomplete. iter2(std::cin) and iter3(std::cin) were also in the program and I thought they were only declarations at this point but it turns out they were responsible for the missing input. Code should have looked like:

std::vector<int> v{};
std::istream_iterator<int> iter(std::cin), iter2(std::cin), iter3(std::cin), eof;

while (iter != eof) {
  v.push_back(*iter);
  ++iter;
}

Lesson learned and apologies. Is it customary to delete terrible questions like this?

2

There are 2 best solutions below

1
On

Constructing more than one iterator may affect the result, as the iterator constructor is allowed to read ahead and buffer the next input.

The standard says [istream.iterator.cons]:

istream_iterator(istream_type& s);

Effects: Initializes in_stream with &s. value may be initialized during construction or the first time it is referenced.

Postcondition: in_stream == &s.

Here, in_stream and value are "exposition only" member variables, used to show that an implementation might buffer the next input, possibly to optimize operator* or to check for end-of-file.

3
On

it should be *iter and not *iterator when you dereference it

    int main()
{
    std::vector<int> v{};
    std::istream_iterator<int> iter(std::cin), eof;

    while (iter != eof) {
        v.push_back(*iter);
        ++iter;
    }

    for (int i = 0; i < v.size(); ++i)
        cout << v[i] << endl;

    return 0;
}

Always pays to use some meaningful names for variables