Vector
Vector

Reputation: 17

Is it variable initialization failure?

Being following the book "Programming Principles and Practice Using C++" by Bjarne Stroustrup for learning C++ right from the very basics. It all proved good until this happened...

int main()
{
      cout << "Please enter your first name and age\n";
      string first_name = "???"; // string variable
      int age = -1; // integer variable
      cin >> first_name >> age; // read a string and then integer
      cout << "Hello, " << first_name << " (age " << age << ")\n";
}

Now, as the above code (under the section Input and Types, Chapter 2) suggests, it outputs a string which familiarizes us to the name and age of a person. As I have initialized the integer variable age to -1, the program must return -1 to the monitor if I, in case by mistake, input a string value into age. The issue is that it just won't happen in my computer. I have tried and compiled and run the program 19 times (I do remember it...) but the result is always the same: it outputs 0 instead of -1.

For e.g. if I enter ABCXYZ 16, then the output will be a nice and simple Hello, ABCXYZ (age 16). But if the input was 16 ABCXYZ, then the output comes out to be Hello, ABCXYZ (age 0), which I expected to be Hello, ABCXYZ (age -1) as the string ABCXYZ won't be read into age (it is an integer variable) and thus give out the initialized value because it wasn't overwritten.

Any idea?

P.S.: I'm using Code:Blocks with GCC - 8.1.0

Upvotes: 0

Views: 210

Answers (2)

user11422223
user11422223

Reputation:

The issue is isolated to the >> operator, where it fails to convert your string input into an integer (which is expected, as std::cin >> x handles expected input, from the type you define for x), and hence returns a 0, irrespective of whatever value you initialized the integer variable with.

This was done since C++ 11 as Kamil mentioned, and conforming to previous standards, the value would have been left unchanged and would return a -1 for your case.

You can check if cin fails or passes for the same to draw a conclusion yourself:

int main() 
{
      int age = -1; 
      std::cin >> age;
      if(cin) 
      std::cout << age; 
}

If you enter an integer (as expected from the type of age) you'd get the output for the value of age you initialized it to, else if you enter a string, cin will fail (and its failbit will be triggered, resulting in false) and nothing will be displayed, in accordance with the if-statement above.

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 140960

std::istream& operator>>(int &value) calls std::num_get::get() internally. From cppreference std::num_get::get() the behavior changed in c++11.

Having v to denote the variable we read into, until c++11 we had:

  • If an error occurs, v is left unchanged.

However since c++11:

  • If the conversion function fails to convert the entire field, the value ​0​ is stored in v

  • If the conversion function results in a positive or negative value too large to fit in the type of v which is a signed integer type, the most positive or negative representable value is stored in v, respectively

  • If the conversion function results in a value not to fit in the type of v which is an unsigned integer type, the most positive representable value is stored in v.

You are compiling using a compiler and C++ standard library configured to be compatible with a standard after c++11, so when std::cin fails to read the field, the value of 0 is stored into age.

Upvotes: 3

Related Questions