30

I am completely new to C++ and am trying to write an extremely basic program, but I am having issues with initializing an integer. I have stripped it down to a very small program that still has the issue:

#include <iostream>
using namespace std;

int main()
{
    cout << "Please enter your age\n";
    int age = -1;
    cin >> age;
    cout <<"\n\n Your age is " << age << "\n\n";
}

I read that if I attempt to input a string, e.g. abc to the age variable, then the input should fail and the value should be left alone and therefore it should print Your age is -1.

However, when I run this program and type abc, then it prints Your age is 0. Why?

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
Thompson
  • 403
  • 4
  • 5

2 Answers2

37

The behavior you want to observe changed in 2011. Until then:

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

But since C++11:

If extraction fails, zero is written to value and failbit is set. [...]

(From cppr.)

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • 10
    What is the rationale for this? – Tobias Brandt Sep 03 '15 at 14:54
  • 9
    I guess it was potentially inefficient to require that the old value be kept around just in case the reading fails. Now, we can immediately start overwriting the old value, and then clear it if there's an error. – Aaron McDaid Sep 03 '15 at 14:58
  • 7
    If efficiency was only the reason, it would make more sense to leave the value unspecified in the event of a failure. It also seems odd that they would break existing code in order to eliminate a simple in-memory move in an operation that will usually be dominated by disk access times (or typing speed, if stdin in a terminal). – Ray Sep 03 '15 at 21:32
5

With the compiler I tested against (gcc 4.8.4), the value is set to zero (for the 'abc' input) regardless of which version of the standard I compile against. Note also that it is set to minimum/maximum values if you provide a valid integer that is outside of the supported range of the variable that you are assigning to.

A more important point though, is that ignoring error flags is a recipe for disaster. Once you have an error in the input, any subsequent input is suspect (without hacks like ignore()). Situations like this are a good candidate for using exception handling.

Here's how I might implement what you are trying to do (but, again, considering the case of multiple inputs, recovering from errors is a messy business):

cin.exceptions( ~std::ios::goodbit );
try { cin >> age; }
catch ( std::ios::failure const & )
   {
   age=-1;
   cin.clear();
   cin.ignore(999,'\n');
   }

or without exeptions:

cin >> age;
if ( cin.fail() ) age=-1, cin.clear(), cin.ignore(999,'\n');

See here for similar questions:

Here are up-to-date docs for the operator in question:

Community
  • 1
  • 1
Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173
  • A related question which I answered some time ago: [C++ input failure: multiple inputs in a single statement](http://stackoverflow.com/q/29244708) – Brent Bradburn Sep 03 '15 at 16:29
  • @LightnessRacesinOrbit: That's what happens when you type everything yourself instead of letting an IDE decide what your style should be. :) – Brent Bradburn Sep 03 '15 at 23:48
  • No it's not! Or it _shouldn't_ be..... Are you saying that you have become so dependent on your IDE for code formatting that you are physically incapable of performing it yourself, despite having infinite time to make an attempt before posting? Because, if so, that's truly disheartening. :( – Lightness Races in Orbit Sep 04 '15 at 02:49
  • 1
    @LRO: I was trying to communicate the opposite of what you understood, but my tone was tongue-in-cheek. I *don't* let an IDE do my formatting. What you find horrendous, just happens to be the way I like it. [To each his own](https://en.wikipedia.org/wiki/Indent_style). – Brent Bradburn Sep 04 '15 at 19:15
  • Formatting plilosophy that I can get behind: [Indenting C Programs](http://www.cs.arizona.edu/~mccann/indent_c.html) – Brent Bradburn May 14 '16 at 22:04
  • FYI I don't get notified by "LRO" – Lightness Races in Orbit May 15 '16 at 15:39
  • @LightnessRacesinOrbit: I know. I was just trying to get the final word. :) – Brent Bradburn May 15 '16 at 17:39
  • I like the idea behind the page, although (a) it's sad that the obvious needs to be stated, and (b) his chosen style is pretty minging! – Lightness Races in Orbit May 15 '16 at 19:12