Exercise 1-6
What does the following program do it, when it asks you for input, you type two names (for example, Samuel Beckett)? Predict the behaviour before running the program, then try it.
#include <iostream>
#include <string>
int main()
{
std::cout << "What is your name? ";
std::string name;
std::cin >> name; // frist std::cin step
std::cout << " Hello, " << name
<< std::endl << "And what is yours?";
std::cin >> name; // second std::cin step
std::cout << "Hello, " << name
<< "; nice to meet you too!" << std::endl;
return 0;
}
Solution
At the first std::cin phase we type in two words, “Samuel Beckett”, followed by hitting the enter key. The following happens:
(1) the two words initially get stored in the buffer (corresponding to std::string variable name)
Samuel Beckett
Note that the buffer automatically discard the leading and trailing blanks. Each word is separated by a space character.
(2) the std::cin cuases the buffer the flush out the first word “Samuel” to the std::string variable assignment. The std::string name has now a value of “Samuel”.
Because the first word has now been flushed out from the buffer, the buffer for name now looks like this:
Beckett
Note that the first word Samuel is now gone. It has been flushed away from the buffer.
At the second std::cin phase, becuase there is already a word in the buffer, it just simply asks the buffer to flush out that value and assign that to the std::string variable name. The std::string name has now a value of “Beckett” (and replace the old value “Samuel”)
Because the first word has now been flushed out from the buffer, the buffer for name now looks like this:
The buffer s now empty!
If there turn out to be a third std::cin step, the user will be asked to supply some values to the buffer, so that the std::cin facility may read from it. (But in this case, the program only has two std::cin steps).
Summary
In summary, the std::cin checks the buffer corresponding to the std::string variable.
- If there is at least one word stored inside the buffer, it flushes the first word from the buffer, read and assign that word to the std::string variable. The program does not need to pause and ask the user to supply values.
- If the buffer is empty, the program would pause and ask the user to supply values (words) to the buffer. Only when there are words inside the buffer, the std::cin would then read from it and assign the value to the std::string variable (and flush that word away from the buffer as a consequence).
Comments
This question appears to be quite simple at first sight, and after going through such detail investigation, it has revealed so much “hidden scene” behind the std::cin and buffer operations. The above summarises my own humble understanding – this is the most logical visualisation I could come up with. (and I hope it is correct!)
For completeness, let us run the program and confirm our understanding.
What is your name? Samuel Beckett
Hello, Samuel
And what is yours?Hello, Beckett; nice to meet you too!
Process returned 0 (0x0) execution time : 21.496 s
Press any key to continue.
Further Experiments
To confirm the hypothesis stated in the summary section above, let’s do three more experiments. Knowing that there are two std::cin steps in the program, we can try the followings:
- Experiment 1: At the first std::cin phase, provide 0 words and hit enter.
- Experiment 2: At the first std::cin phase, provide 1 word and hit enter.
- Experiment 3: At the first std::cin phase, provide 3 words and hit enter.
Results to Experiments
Experiment 1
At the first std::cin phase, I provide 0 words and hit enter.
Result to Experiment 1
Because the buffer for the std::string variable is empty, hitting the enter button does not get us anywhere – the program insists us to provide at least 1 word to the buffer.
Experiment 2
At the first std::cin phase, I provide 1 word and hit enter.
Result to Experiment 2
This satisfies the first std::cin phase – it reads the word that I provide and use it for the first std::cout phase. Buffer is empty as a consequence. When it reaches the second std::cin phase however, because the buffer is empty it pauses and asks me to provide some words in order to proceed.
Result Experiment 3
At the first std::cin phase, I provide 3 words and hit enter.
Result:
- The initial buffer contains 3 words.
- The first std::cin flushes first word from the buffer. The buffer contains the remaining 2 words as a consequence.
- The following std::cin flushes first word from the buffer. The buffer contains the remaining 1 word as a consequence.
(note: we the program contains a 3rd std::cin step, it would just read that remaining 1 word from the buffer).
Reference
Koenig, Andrew & Moo, Barbara E., Accelerated C++, Addison-Wesley, 2000