Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

A question about the standard input stream std::cin and how it parses out double and ints

i am reading programming: principles and practice using c++. Currently im doing exercices for chapter 3, however one kind of stumped me. Now i was able to get the code working and all, but i was perplexed more about the programs reaction to my input.

Here’s the question:
Write a program that prompts the user to enter two integer values. Store these values in int variables named val1 and val2. Write your program to determine the smaller, larger, sum, difference, product, and ratio of these values and report them to the user.

Here is my code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

   cout << "Hello, please enter two integers: ";

   int val1;
   int val2;
   int garbage;

   cin >> val1 >> val2 >> garbage;

   cout << "Val1: " << val1
     << "\nVal2: " << val2
     << "\nGarbage: " << garbage << '\n';


   if (val1 < val2)
    cout << "\nval1 is smaller than val2.";

   if (val1 > val2)
    cout << "\nval1 is bigger than val2.";

   int sum = val1 + val2;
   int difference = val1 - val2;
   int product = val1 * val2;
   double ratio = 1.0 * val1 / val2;

   cout << "\nRatio: " << ratio
     << "\nSum: " << sum
     << "\nDifference: " << difference
     << "\nProduct: " << product << '\n';

Can somehow explain to me more in depth what is supposed to happen in this situation regarding what the operator >> and cin are doing behind the scenes, and why ratio becomes "inf" after i input the string "90.8 9" in my program?

Thank you.

Now what i have done instead of inputting straight ints is to input doubles to see what would happen. Now obviously i am aware that cin parses out values according to which type the second operand of the >> operator is. But what i have done is input the following string into the program: "90.8 and 9"

Somehow the ratio variable is output on the screen as "inf"
and val2 is 0.

Val2 could be zero because of how >> operates, which is that if it detects a string when it is supposed to detect an int for an integer variable, >> adjusts the value of the second operand to 0. But i am not sure…

The "garbage" variable is just for me, i thought that cin did the following: See the value 90, input the value 90 in val1, see a string with the characters .8 and input 0 in val2, input 9 into garbage.
But for some reason 9 is not being inputted in "garbage". Garbage is now a literal garbage value with a random integer inside of it.

Here’s the output of my program:

Hello, please enter two integers: 90.8 9
Val1: 90
Val2: 0
Garbage: -858993460

val1 is bigger than val2.
Ratio: inf
Sum: 90
Difference: 90
Product: 0

>Solution :

In this line

cin >> val1 >> val2 >> garbage;

when you enter 90.8 9 what happens in the following:

  1. cin tries to read an integer. I sucessfully parses 90 and stores that in val1.
  2. Next cin tries to parse another integer but it encounters a . as next character. Hence, extraction of the int fails and 0 is assigned to val2. std::cin is now in a fail state and no further extraction will happen until you clear its state.
  3. cin does not attempt to extract more because it is in a fail state. Hence it will also not assign 0 to garbage. Hence garbage has an indeterminate value. You cannot read it or print it to the screen. Your code does it nevertheless, which means your code has undefined behavior, its output could be anything.

This thingy about assigning 0 was only introduced in C++11. And I still find it somewhat surprising that >> works like this when it fails in compound expressions. You can either check the state of cin after the extraction and when any failed assume that all of them failed.

if (cin >> val1 >> val2 ) {
   // ok
} else { 
   // either val2 or val2 and val1 were not sucessfully extracted
}

Or alternatively use seperate expressions and check after each extraction:

if( cin >> val1) {
    // sucessfully read 
    // val1 is safe to use 
else {
    // handle failure
}
if (cin >> val2) {
   ...etc...

Then in this line

double ratio = 1.0 * val1 / val2;

when val1 = 90 and val2 = 0. What happens is that 1.0 * val1 is evaluated first to yield a value of val1 but as a double. The line is basically the same as

double ration = static_cast<double>(val1) / val2;

Hence the division uses floating point division (not integer division where division by 0 is undefined) and the result is inf.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading