Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating over int and string with istream_iterator

Tags:

c++

I am going through The C++ Programming Language Book and reached "Iterators and I/O" page 61 they give the following example to demonstrate iterating through a string submitted.

#include <iostream>
#include <iterator>
#include <string>

using namespace std;

int main()
{

    istream_iterator<string>ii(cin);
    istream_iterator<string>eos;

    string s1 = *ii;
    ++ii;
    string s2 = *ii;

    cout <<s1 << ' '<< s2 <<'\n';
}

Which I totally understand, now I was playing around with this example to make it work for numbers as well. I tried adding in the following in the respective places...

istream_iterator<int>jj(cin);
int i1 = *jj;
cout <<s1 << ''<< s2 << ''<< i1 <<'\n';

Which does not give me the chance to input the number section when running the program. Why is this so ? Can the iterator only be used once on cin ? such that it is already has input from cin so the next iterator is ignored ?


Edit here is what I have after insertions

#include <iostream>
#include <iterator>
#include <string>

using namespace std;

int main()
{

    istream_iterator<string>ii(cin);
    istream_iterator<string>eos;

    //istream_iterator<int>dd(cin);

    string s1 = *ii;
    ++ii;
    string s2 = *ii;
    //int d = *dd;
    int d =24;
    cout <<s1 << ' '<<s2<<' '<<d<< '\n';
}

The above works for

Hello World or
Hello
World

Giving Hello World as the output.

removing the comments from

istream_iterator<int>dd(cin);
int d = *dd;

and commenting out

int d =24;

Leads to Hello Hello 0 as the output.

like image 579
phwd Avatar asked Nov 12 '10 00:11

phwd


1 Answers

When you first create an istream_iterator, it gets the first input and stores the data internally. In order to get more data, you call operator++. So here's what's happening in your code:

int main()
{

    istream_iterator<string>ii(cin);  // gets the first string "Hello"
    istream_iterator<int>jj(cin); // tries to get an int, but fails and puts cin in an error state

    string s1 = *ii; // stores "Hello" in s1
    ++ii;            // Tries to get the next string, but can't because cin is in an error state
    string s2 = *ii; // stores "Hello" in s2
    int i1 = *jj;    // since the previous attempt to get an int failed, this gets the default value, which is 0

    cout <<s1 << ' '<<s2 <<' '<< i1 << '\n';
}

Here's what you want to do:

int main()
{

    istream_iterator<string>ii(cin);

    string s1 = *ii;
    ++ii;
    string s2 = *ii;

    istream_iterator<int>jj(cin);
    int i1 = *jj;

    // after this, you can use the iterators alternatingly,
    //  calling operator++ to get the next input each time

    cout <<s1 << ' '<<s2 <<' '<< i1 << '\n';
}
like image 92
Benjamin Lindley Avatar answered Sep 27 '22 22:09

Benjamin Lindley