shangping
shangping

Reputation: 1001

cin stream infinite loop, why?

I copied this simple program from c++ programming language, but I cannot get it work as desired. Am I missing something? Basically, the program will output "input end" after I hit return, and then repeat input from cin. It is never able to go to the next statement. I tried to use the vector (commented two statements below), the same. Tried on Vc6 and vs2008.

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

map<string, int> histogram;
void record(const string &s)
{
    histogram[s]++; //this is pretty strange, however it does work!
    cout<<"recorded:"<<s<<" occurance="<<histogram[s]<<"\n";
}

void print(const pair<const string,int> &r)
{
    cout<<r.first<<' '<<r.second<<'\n';
}

int main()
{
    istream_iterator<string> ii(cin);
    istream_iterator<string> eos;
    cout<<"input end\n";

    for_each(ii,eos,record); //this statement cannot get out why? It repeats the keyboard input
    //vector<string> b(ii,eos);
    //for_each(b.begin(),b.end(),record);
    for_each(histogram.begin(),histogram.end(),print); //program never comes here why?
}

Running results:

a b c

input end

recorded:a occurance=1

recorded:b occurance=1

recorded:c occurance=1

1 2 3

recorded:1 occurance=1

recorded:2 occurance=1

recorded:3 occurance=1

Upvotes: 5

Views: 440

Answers (1)

Sven
Sven

Reputation: 22703

istream_iterator will continue until it hits the end of the stream, which on cin doesn't normally happen.

cin will encounter an end-of-stream, causing your statement to terminate, when it was redirected to a file (when it reaches the end of the file), or if it's receiving console input you can send an end-of-stream by pressing CTRL-Z (CTRL-D on Linux, iirc). You may need to press enter afterwards.

Note that cin will be unusable after you do this, so you cannot read more input after that point.

Until the end-of-stream is encountered, ii will remain valid and continue to request more data from the stream (in thie case the console).

The solution would be to not use for_each but a manual while loop which you can break out of when whatever condition you want is satisfied.

Upvotes: 5

Related Questions