I'm using istream_iterator to read input from standard i/p and writing it to standard o/p using ostream_iterator. I expected it to print the input to the console when I hit enter and then exit but it loops for next input after printing and so on.

#include <iostream>
#include <iterator>
#include <algorithm>

int main(){
                std::ostream_iterator<std::string>(std::cout," "));


You are copying the content of the cin stream, so it will never end until you press Enter, maybe. So it never ends.

Sorry, your answer is not clear. I do press enter but it takes in one line, prints it out and then waits for another instead of terminating.

It'll read until eof. Use ctrl-z (on windows) to end it.

the copy() function will try and increment the iterator on std::cin until it finds this null istream_iterator (which I doubt is a correct use, but I'm not so familiar with this class). The problem is that std::cin is special in the sense that every time to increment the iterator it will wait for a new line before outputting the new iterator. In other words, it can not test that the new iterator is eof or null or whatever until you enter a new line, and then it is not "invalid". So that's why this code is endless. And philosophically speaking, how can the program tell when the user is done inputting stuff? Unless you set some real end-condition, the copy() function will not guess it.

The default constructor of istream_iterator points to eos (end of stream) and copy goes from the first iterator to second and copies to the ostream_iterator. So, assuming that the eos charachter is newline, once I hit enter the copy should stop because the second iterator is reached.

@Nick i find it strange that we have to use ctrl_z to end this, because this is given at a lot of places as the code to copy strings from standard i/p directly into vectors or file. ending this with ctrl_z defeats the purpose i guess. Check this link for many such examples, but none of them work for me :( link

I see first that a lot of these examples use integer delimited with spaces, and newline triggering the end-of-stream. But in your example end-of-line delimits the strings by default, but what triggers the end-of-stream? should it be set as format for std::cin? Is it OS-dependent?

In other words if newline is used to delimit strings that are captured by the istream_iterator, then every time you hit enter you will get a new string captured and outputted in std::cout, but there is no way for the computer to know what enter-strokes mean "put a new string" and which mean "end the program or string capture". This is really what copy does and I tested and it behaves exactly as your program:

std::istream_iterator<std::string> Iter(std::cin);
  std::istream_iterator<std::string> eos;

  while (Iter != eos) {
    std::cout << *Iter << std::endl;

There is not exit condition because no action from the user can trigger eos. It would make this bizzarely impossible:

  std::istream_iterator<std::string> Iter(std::cin);
  while (Iter != eos) {
    std::cout << *Iter << std::endl; Iter++;
  }; };
  {... do something ...}
  std::istream_iterator<std::string> Iter(std::cin);
  while (Iter != eos) {
    std::cout << *Iter << std::endl; Iter++;
  }; }; //PROBLEM: std::cin has already reached eos, so input cannot resume!

But this is just my humble opinion, a better expert is needed for istream related stuff. I usually isolate cin in my apps with a kind buffer class of my own.

I think this thread addresses the issue very well:


Simply put, the std::cin will not reach end-of-stream until the user presses ctrl-D or kills the app. From the last example on the previous post, it is pretty clear why it doesn't make sense for eos to be reached unless the app is about to die, because the user can always enter characters until that point or until he detaches the terminal from the app.

commented: thanks !! +3

@mike, that does clear quite a few things. Thanks and welcome to Daniweb !!