I am curious why cin
behaves in the following way. I think I might have
some misunderstanding about its behavior.
Consider this simple code. This code is asks for some input to be entered, all of which is printed out in the last statement.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
cout << "Please enter your input: " ;
int a=3, b=87; // initialized to some random integers
string s = "Mary" ; // initialized to a random string
cin >> a ;
cin >> b ;
getline(cin,s);
cout << "You entered the following " << a << " " << b << " " << s << endl;
return 0;
}
Now if the input is 12 34 cat
the output is 12 34 cat
This is expected.
However if the input is cat 23 dog
the output is 0 87 Mary
.
Here is why I think this is unexpected:
cin >> a
should fail since cat
cannot be converted into an integer. However, a
gets replaced with what I presume is a garbage value.
Now since the second number of the input is an integer 23, cin >> b
must succeed. Yet this operation seems to fail, and b
continues to retain its original value unlike what happened to a
.
Similarly getline
fails to place the string <space>dog
into the string s
which continues to retain its original value of Mary
.
My questions are the following.
Does the failure of some cin
operation mandate the failure of all
subsequent cin
operations using the >>
operator or the getline
function.
Why did the failure of the first cin
operation change the value of a
whereas the initial values of b
and s
were unchanged?
The "c" in C++ cin refers to "character" and "in" means "input". Thus, cin means "character input". The C++ cin object belongs to the istream class. It accepts input from a standard input device, such as a keyboard, and is linked to stdin, the regular C input source.
cin Syntax The syntax of the cin object is: cin >> var_name; Here, >> is the extraction operator.
Standard input stream (cin) It is connected with the standard input device, which is usually a keyboard. The cin is used in conjunction with stream extraction operator (>>) to read the input from a console. Let's see the simple example of standard input stream (cin): #include <iostream>
The usage of cin is simple, too, and as cin is used for input, it is accompanied by the variable you want to be storing the input data in: std::cin >> Variable; Thus, cin is followed by the extraction operator >> (extracts data from the input stream), which is followed by the variable where the data needs to be stored.
Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.
Yes. Until you clear the error with cin.clear()
. Also, when an extraction fails, the characters are left in the buffer, so if you try to read the same type again, it will fail again.
Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?
Because (since C++11), it is defined to change the value to 0 in case of failed extraction from a (previously) valid stream. Before C++11, it would have been left unchanged. For a stream in an error state, the operation does nothing, which is why b
and s
are unchanged.
- Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.
Yes. Your code expects to read the input value in exactly that order
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value
Giving it a input like
cat 23 dog
leads to setting fail()
state on cin
when trying to read the 1st int
value, and none of the following operator>>()
calls will succeed.
cin >> a
should fail sincecat
cannot be converted into an integer. However,a
gets replaced with what I presume is a garbage value.
It's no garbage value but well defined, see the reference citation below.
Now since the second number of the input is an integer 23,
cin >> b
must succeed. Yet this operation seems to fail, andb
continues to retain its original value unlike what happened toa
.
No this assumption is wrong, as mentioned cin
is in fail()
state at this point, and parsing further input is skipped at all.
You have to call clear()
after each operator>>()
call, to be sure the input will by parsed:
cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value
- Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?
Because the reference of std::basic_istream::operator>>()
says
"If extraction fails, zero is written to value and
failbit
is set. If extraction results in the value too large or too small to fit in value,std::numeric_limits<T>::max()
orstd::numeric_limits<T>::min()
is written andfailbit
flag is set. (since C++11)"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With