2

So I've been pulling my hair out about this since yesterday, I've checked multiple posts on here trying to figure this out, basically, I'm trying to read 1 or more lines from standard input into a string variable then use an istringstream to get integer values. This is what i have:

string line;
int num;

while(getline(cin, line)){

    istringstream data(line);

    while(data >> num){

        do stuff...
    }
}

However, the outer loop never exits, if there is no input in the standard input it just sits there waiting and never actually exits the loop, so the program basically pauses until something is entered, and then just continues the loop once more. Can someone tell me why getline doesn't just cause an exit condition when there is nothing on stdin, and can someone help me to fix this issue, your help will be greatly appreciated.

  • It's the same reason why water is wet and the sky is blue: when reading from standard input that, by default, comes from the terminal console, if no input is available the program pauses and waits until input is typed in. That's how C++ works. – Sam Varshavchik Oct 06 '16 at 20:52
  • @SamVarshavchik Yes but isn't getline supposed to cause the while condition to evaluate to false if there is no more input? if not then how can i achieve this? –  Oct 06 '16 at 20:54
  • 1
    @Kakarot If you feed the data from the file (redirect stdin) it should terminate. – ciechowoj Oct 06 '16 at 21:00
  • 1
    `getline()` will evaluate false on error or an end-of-file condition. An end-of-file condition is specified for interactive terminal input by either CTRL-Z or CTRL-D, depending on the operating system. – Sam Varshavchik Oct 06 '16 at 21:01

2 Answers2

2

if there is no input in the standard input it just sits there waiting and never actually exits the loop, so the program basically pauses until something is entered, and then just continues the loop once more. Can someone tell me why getline doesn't just cause an exit condition when there is nothing on stdin

It just behaves as expected. What is "nothing on stdin" actually? Did you mean an empty input? In that case you might want to change your loop condition to

while(getline(cin, line) && !line.empty()){

Also as mentioned in the comments CTRL-Z or CTRL-D (depends on OS) followed with ENTER input may end the loop.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • When I say nothing on stdin I mean for eg. if the user enters 1 2. 2 will be the last thing on that line and getline should stop reading and terminate after this –  Oct 06 '16 at 21:14
  • @Kakarot If there's just an empty ENTER, change the condition as I've shown. There's nothing left actually. – πάντα ῥεῖ Oct 06 '16 at 21:15
  • @Kakarot Post a [MCVE] that reproduces the behavior you claim. Your question isn't complete it seems. – πάντα ῥεῖ Oct 06 '16 at 21:17
  • I just tested this answer. It works, @kakarot, you're not doing something incorrectly. – Mark S Oct 06 '16 at 22:02
  • Ctrl-Z or Ctrl-D *may* need to be followed by Enter. – Mark Ransom Oct 06 '16 at 22:03
  • I said "may" because I think it's different between Windows and *nix, and I can't remember which needs which. – Mark Ransom Oct 06 '16 at 22:07
  • Yeah, it works, when I enter ctrl-d, it's not exactly what I was looking for but i'll have to make it do, what's great is that I have a better understanding of cin now. Thanks! –  Oct 06 '16 at 22:08
1

The problem is that the standard input (cin) will read one line and since getline returned 'true' (a reference != 0) the loop will continue forever asking for another line.

If you want to read one line from input, you should avoid the while:

string line;
int num;

getline(cin, line)){

istringstream data(line);

while(data >> num){

    do stuff...
}
Emi Höss
  • 86
  • 4