7

I have written this code in C++ in the CodeBlocks IDE but when I run it, it doesn't give me -1 if it doesn't read a number, it gives me 0. Is there something wrong with the code?

#include "iostream"

using namespace std;

int main()
{
    cout<<"Please enter your first name and age:\n";
    string first_name="???"; //string variable
                            //("???" means "don't know the name")
    int age=-1; //integer variable (-1 means "don't know the age")
    cin>>first_name>>age; //read a string followed by an integer
    cout<<"Hello, " <<first_name<<" (age "<<age<<")\n";

    return 0;
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
calm-tedesco
  • 256
  • 5
  • 12

2 Answers2

11

The behaviour of std::basic_istream::operator>> has changed from C++11. Since C++11,

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::max() or std::numeric_limits::min() is written and failbit flag is set.

Note that until C++11,

If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.

You could check the result by std::basic_ios::fail or std::basic_ios::operator! and set the default value by yourself. Such as,

string first_name;
if (!(cin>>first_name)) {
    first_name = "???";
    cin.clear(); //Reset stream state after failure
}

int age;
if (!(cin>>age)) {
    age = -1;
    cin.clear(); //Reset stream state after failure
}

cout<<"Hello, " <<first_name<<" (age "<<age<<")\n";

See also: Resetting the State of a Stream

Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 1
    I would address OP on how to check failbit (and then set the default value). I would also point him [here: Resetting the State of a Stream](http://stackoverflow.com/questions/11246960/resetting-the-state-of-a-stream) – Antonio Nov 04 '15 at 10:57
  • I think OP is more interested in setting the default value in that case. (And I would also reset the status of the stream) – Antonio Nov 04 '15 at 11:03
  • Who's OP? And why when I asked a friend of mine to write the exact same code in Visual Studio 2015 it gave him `-1` if it didn't read a number? Is it something about the IDE? @songyuanyao – calm-tedesco Nov 04 '15 at 11:18
  • 1
    @Alberto **O**riginal **P**oster - the author of the question. And Visual Studio is generally quite sloppy in following the standard. It's very possible their standard library still follows C++03 behaviour in this regard. – Angew is no longer proud of SO Nov 04 '15 at 11:20
  • @Alberto As Angew said, VS2015 might not support this c++11 feature yet, or you need to specify some compile option to enable it. Anyway, if you check the input result and set the default value by yourself (as the code in my answer), it will work well for both the compilers support the feature or not. – songyuanyao Nov 04 '15 at 11:30
  • Thank you all for the answers. – calm-tedesco Nov 04 '15 at 11:32
  • I wonder how can the first cin fail, and if probably to make cin usable again you need to reset the state of the stream http://stackoverflow.com/questions/11246960/resetting-the-state-of-a-stream – Antonio Nov 04 '15 at 14:00
0

There is no support for custom default values when reading from std::cin. You have to read the user input as a string and check if it's empty. See this question for details.

Quoting from the linked question:

int age = -1;
std::string input;
std::getline( std::cin, input );
if ( !input.empty() ) {
    std::istringstream stream( input );
    stream >> age;
}
Community
  • 1
  • 1
Lukas Boersma
  • 1,022
  • 8
  • 26