Search code examples
c++stlistream-iterator

istream_iterator behaviour


I have two pieces of code.They work properly when it is used alone in the main().

vector<int> v;

cout << "Enter sequance of integers "<< "(press q to quit) : ";
istream_iterator<int> start_cin(cin);
istream_iterator<int> end_of_cin;
copy(start_cin,end_of_cin,back_inserter(v));

for ( vector<int>::iterator It = v.begin();It != v.end(); It++ )
    cout << *It << "\t";
cout << endl;

and

vector<string> vS;
cout << "Enter three strings : ";
for ( int i = 0; i < 3; i++ )
    vS.push_back(*istream_iterator<string>(cin));

ostream_iterator<string> sIt(cout,", ");
copy(vS.begin(),vS.end(),sIt);
cout << endl;

When these two part use together,i.e

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <string>
using namespace std;

int main ()
{
    // first part

    vector<int> v;

    cout << "Enter sequance of integers "<< "(press q to quit) : ";
    istream_iterator<int> start_cin(cin);
    istream_iterator<int> end_of_cin;
    copy(start_cin,end_of_cin,back_inserter(v));

    for ( vector<int>::iterator It = v.begin();It != v.end(); It++ )
        cout << *It << " \t";
    cout << endl;


    vector<string> vS;
    cout << "Enter three strings : ";
    for ( int i = 0; i < 3; i++ )
        vS.push_back(*istream_iterator<string>(cin));

    ostream_iterator<string> sIt(cout,", ");
    copy(vS.begin(),vS.end(),sIt);

    cout << endl;

    return 0;
}

here first part worked but second part give output: Enter Three Strings : , , ,. I want to know that what is the reason behind this behaviour?

Thanks.


Solution

  • After the copy() has completed cin will be in an unreadable state (!cin.good()), due to the failed read of the "integer" q. This means the subsequent for loop will fail to read anything.

    Add:

    cin.clear();
    cin.ignore(); // To skip the unread "q"
    

    before the for loop.

    EDIT:

    As commented by James Kanze, check to ensure "q" was the cause of the termination of the copy():

    ...
    
    cin.clear();
    string int_read_terminator;
    cin >> int_read_terminator;
    if ("q" != int_read_terminator)
    {
        cerr << "Integer copy() failure: " << int_read_terminator << "\n";
    }
    else
    {
        ...