Unexpected program end

Execution of the following code drops to the system prompt after the point where it displays Enter text:. Why? Thanks.

#include <iostream>

using namespace std;

int main()
{
string original_text;
string keyboard_input;
int user_choice;
cout << "Enter 1 for file input; 2 for keyboard input: ";
cin >> user_choice;
cout << "\n" << user_choice << endl;
cout << "\n\nEnter text:\n";
getline(cin, keyboard_input);
cout << keyboard_input << endl;
original_text = keyboard_input;
cout << "\n\n" << original_text << endl;

return 0;
}


Parenthetically, the above code is watered down from a larger source file for the purpose of testing.
The issue lies one using cin and getline together in the same program on a windows machine. To put it simply, Windows is the ultimate issue here.

Why?

A new line on a window's system is composed of two seperate characters:
'\r' - Carriage return (terminates the current line)
'\n' - New line (begins a new line)

Why is this an issue?
cin works in mysterious ways (not really, just more advanced than what needs to be explained here) by accepting user input and shoving it into a variable that the coder (you) provide and then discards whitespace. Whitespace in this context is either a space, tab, and new lines. On other systems, a new line is either '\n' or '\r', but windows uses both. cin will discard one, regardless of the OS. In the case of windows, there is still an character left in the buffer '\n'.

How do we fix this?
Simple. Use cin.ignore(). Doing a little research, we see there is a few ways to use this, but the simplest way is to use a number for the first parameter (I typically use 80), and a delimiting character ('\n'). Ignore does exactly what it says, it ignores x (80) characters in the buffer up until it reaches the delimiter ('\n').

Why this is important?
cin, by default, ignores any whitespace in the stream first. This is great. However, getline (along with get) doesn't ignore whitespace, and reads directly from the buffer. This causes the code to look like it skips the getline statement.

Conclusion:
Add cin.ignore(80, '\n'); right before the getline statement.
@Volatile Pulse (1121)

Thanks. The code you suggested works.

If you don't mind a follow-on, am I correct in interpreting your explanation as saying that the statement using getline read the extra \n in the buffer without waiting for user input, the value of keyboard_input became \n, the cursor dropped down a line, and the program ended?
The issue lies one using cin and getline together in the same program on a windows machine. To put it simply, Windows is the ultimate issue here.


I don't think this is the case as IIRC the standard streams will always use '\n' as the newline character. When it is output or input it will be converted to the OS/systems newline for you.

getline read the extra \n in the buffer without waiting for user input, the value of keyboard_input became \n, the cursor dropped down a line, and the program ended?


Not exactly. getline/cin don't ever "wait for user input" specifically. They simply read out of a buffer that (in this case) is filled with user input. If the buffer is empty, then they will wait until it gets data, which (in this case) comes in when the user hits enter.

Since there is still data in the buffer, they don't need to wait and hence they will read immediately.
@firedraco

Thanks for the clarification.
@firedraco
IIRC, the console reads information directly from the OS, unless specifically implied (piped from a file) and then the streams read from the console itself. I may be wrong on this, but I don't believe that any other OS's have this issue aside from Windows. The only thing I've been able to narrow it down to is that the newline character on the Window's OS is what causes it specifically. It's the only one with two actual characters. The streams actually treat '\n' AND '\r' as terminating characters (they're both classified as whitespace) so that it can handle OS's that use '\r' for a line return.

Regardless, the issue lies within an extra character chilling in the buffer.
Topic archived. No new replies allowed.