1

I wanted to test behavior of std::cin when an unexpected input is given. Why does std::cin return 0 and 2.07386e-317 in a non-deterministic way?

#include <iostream>

using namespace std;

int main(){
    double foo, bar;
    while(cin.good() and cin >> foo >> bar){    
        cout << foo << " " << bar << endl;
    }
    if (cin.eof()){
            cout << "Ooops, EOF encountered.\n";
    }
    else{
        cout << "Something weird happened!\n";
        cout << foo << " " << bar << endl;
    }
    return 0;
}

Whenever I type,

 <a_number> <non-number>

Output is <a_number> 0

And whenever I type,

<non-number> <anything>

Output is 0 2.07386e-317


I tried exact code by increasing number of input to 3 and,

<non-number> <non-number> <non-number>

Output is 0 0 2.07353e-317


For 4 inputs,

`<non-number> <non-number> <non-number> <non-number>`

Output is 0 2.07353e-317 0 2.07353e-317


Lastly, for 5 inputs,

`<non-number> <non-number> <non-number> <non-number> <non-number>`

Output is 0 2.07353e-317 2.07353e-317 0 2.07353e-317

I looked at the November 2014 working draft of current standart (C++14) and couldn't see any helpful information on this at § 27.4.2 where Narrow stream objects are explained in a surprisingly short way. I expected to see internal working details of std::cin. Am I missing something?

I am curious about the reasons of behavior. Appreciate the help.

oguzhan
  • 193
  • 9
  • Using values of uninitialized non-static local variables, which are indeterminate, isn't good. Try initializing the variables, and [you'll see](http://melpon.org/wandbox/permlink/peBxVVt3QD7lvLpJ) the number used to initialize appearing. – MikeCAT Mar 03 '16 at 01:01
  • @MikeCAT Tried all variables as static and observed all outputs as 0, as their initial value. Then is it a coincidence to see previous values all the time either 0 or 2.07353e-317? Thanks. – oguzhan Mar 03 '16 at 01:05
  • Did you make `and` a macro of `(&&)`? – Colin Basnett Mar 03 '16 at 01:06
  • 1
    @ColinBasnett It is actually a builtin operator, see http://en.cppreference.com/w/cpp/language/operator_logical. – oguzhan Mar 03 '16 at 01:08

1 Answers1

2

You shouldn't try to print the variables in the "Something weird happened" case, because that means the variable extraction wasn't successful. Any of the variables starting from the first incorrect input will not have been assigned.

See How to test whether stringstream operator>> has parsed a bad type and skip it for how you can skip over bad inputs.

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks for reminding to check status of cin object after extraction! However, please look at https://ideone.com/QTseTC . Results are even different now. – oguzhan Mar 03 '16 at 01:28
  • Why are you trying to print the variables when something weird happened? That means the variables were never assigned. – Barmar Mar 03 '16 at 01:29
  • I was just curious how std::cin'd react to different conditions and I considered that but I still don't know exactly which stage of reading input fails here. After reading fully complete and at checking? While reading? etc. Does that failed reading strictly means not to assign variable a value? That's actually the base reason of my confusion cause I don't know working principles of std::cin. Could you refer to a reliable source on this? Thank you. – oguzhan Mar 03 '16 at 01:36
  • `cin >> foo >> bar` is equivalent to `(cin.operator>>(foo)).operator>>(bar)`. So it tries to do the first extraction, and whether or not it succeeds or fails it tries to do the second one. If you want to perform error checking, you shouldn't chain them. – Barmar Mar 03 '16 at 01:40
  • I've removed the first part of my answer. When a stream is converted to boolean, it indicates whether its `failbit` is clear. – Barmar Mar 03 '16 at 01:44
  • Thank you, I actually knew to check flags of cin object and skip unexpected input. I guess we accept failed reading absolutely results not in an assigment. Then, the outputs I shared and the ones at ideone are just uninitialized variable values from stack, right? – oguzhan Mar 03 '16 at 01:51
  • Exactly. That was in the first comment below your question. – Barmar Mar 03 '16 at 01:54
  • There was a reason to reply to that comment with a question but that's about getting same values again and again. Run on different machine, got different results and cleared mind, it's not about std::cin. Then what is it about? Have any idea? Clear on the question by the way, thank you! – oguzhan Mar 03 '16 at 01:59
  • You're seeing the uninitialized values of the variables. That's undefined behavior, so you see different values. – Barmar Mar 03 '16 at 02:00
  • Yes absolutely, but I was asking why the values come **same all the time in the same machine** but since that is an undefined behavior, let's close the file. I just wondered if there is a logical reason for that. Anyway, big thanks, appreciate your effort! – oguzhan Mar 03 '16 at 02:04
  • Computers are generally deterministic. Every time you run a program, its memory is initialized the same way. So the uninitialized values of variables will usually be the same. – Barmar Mar 03 '16 at 02:07
  • That makes somewhat sense. Thanks a lot. – oguzhan Mar 03 '16 at 02:13