Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clarification on a basic behavior of cin in C++

Tags:

c++

cin

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 catcannot 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.

  1. Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.

  2. Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?

like image 922
curiousexplorer Avatar asked May 26 '15 17:05

curiousexplorer


People also ask

What is CIN function in c?

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.

What is the syntax for CIN () statement?

cin Syntax The syntax of the cin object is: cin >> var_name; Here, >> is the extraction operator.

What is CIN example?

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>

How do you use the cin function?

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.


2 Answers

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.

like image 78
Benjamin Lindley Avatar answered Sep 22 '22 17:09

Benjamin Lindley


  1. 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 since catcannot 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, and b continues to retain its original value unlike what happened to a.

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

  1. 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() or std::numeric_limits<T>::min() is written and failbit flag is set. (since C++11)"

like image 24
πάντα ῥεῖ Avatar answered Sep 25 '22 17:09

πάντα ῥεῖ