So you're saying I shouldn't use extractor and getline simultaneously in code. Even if they're separated from each other. |
Let me explain what the problem is...
The input from the user is just a sequence of characters. This is also known as a
stream (std::cin and objects of type std::istringstream are "input streams").
When the user press enter to feed a line of input to the program there will be a newline character (
'\n'
) added at the end.
When you read from the stream it will read character by character, continuing from where it left off earlier.
When you use getline it will read all characters until it finds a newline character.
When you use >> it will first ignore any whitespace character and then it will read the value. Anything that comes after the value (including the newline character at the end of the line) is still left in the stream for other operations to read.
Now, let's consider the following code:
1 2 3 4 5 6 7 8
|
char ch;
std::cin >> ch;
std::string line;
std::getline(std::cin, line);
std::cout << "char: '" << ch << "'\n";
std::cout << "line: '" << line << "'\n";
|
If you write
A and press enter the stream will contain "A\n".
std::cin >> ch;
reads the
A and leaves newline character in the stream "\n".
Then
std::getline(std::cin, line);
will run and start looking for a newline character. It finds one right away so it gives you an empty string (without waiting for more input).
If you instead write
Hello and press enter the stream will contain "Hello\n".
std::cin >> ch;
reads the
H and the stream is left with the content "ello\n".
Then
std::getline(std::cin, line);
reads all the characters "ello" up until the newline character and store them in the string.
Sometimes this is what you want. You might want to read whatever is left on the line after reading something at the beginning of the line with >>. But usually (as is the case in your program) it's not what you want and that's why you need to work around this somehow.
In the first one as you showed I can't use getline with char inputs. I can convert a char variable into a string but it can hold more storage than char, doesn't it? |
Yes. That's why I said you can use a std::istringstream to extract a char, or whatever data type you want, from the line string.
I'm not understanding your second one. |
The ignore function is used to discard characters from the stream. It will stop when it has discarded as many characters as specified by the first argument, or as soon as it finds the character that was passed as the second argument, whichever comes first.
In this case I wanted to discard the rest of the line. That's why I passed the newline character as the second argument.
And I don't care how long the line is so that is why I passed the *maximum possible value as the first argument.
* The first argument should be of type std::streamsize (or a type that is implicitly convertible to std::streamsize).
std::numeric_limits<std::streamsize>::max() is the maximum value that the type std::streamsize can store.
See
https://www.cplusplus.com/reference/istream/istream/ignore/
https://www.cplusplus.com/reference/limits/numeric_limits/
https://www.cplusplus.com/reference/ios/streamsize/
That said, just passing some large integer is probably also fine.
|
std::cin.ignore(1000, '\n');
|
Who writes lines that are longer than 1000 character, right?
As well as the third one. |
The line
|
std::getline(std::cin >> std::ws, line);
|
has the same meaning as
1 2
|
std::cin >> std::ws;
std::getline(std::cin, line);
|
std::cin >> std::ws
discards all leading whitespace characters. If the stream only contained a newline character before then it will discard the newline character and wait for more input (and continue to discard all whitespace characters) until the user enters a non-whitespace character.
Edit: In the first one you forgot the mention about <sstream> |
Some of the things that I mention here requires additional headers. You'll have to look into that yourself. ;)
It's time for me to sleep now so I won't be able to respond to any follow up questions in the next few hours, just so that you know... 😴