开发者

Should C++ keep variables intact on input failure?

Doesn't C++ offer any guarantee about keeping variables intact on input failure? With older versions of gcc, a program like this one keeps the -1 value of i on failure (for instance if a letter is typed instead of a number on input). With Ubuntu 10.10 (gcc 4.4.5), i is reset to zero in case of input failure.

#include <iostream>

int main()
{
 int i = -1;
 std::cin >> i;
 std::cout << "i = " << i << '\n';
 return 0;
}

This behavior br开发者_如何学JAVAeaks a lot of my code. I suppose the gcc people know what they are doing, and it is likely to be my mistake. If anyone knows the standard, I'd like to know what it says about this situation.

Thanks.


Don't rely on the variable. Rely on the state of the stream:

if (std::cin >> i) // "if (!std::cin.fail())" would also work
{
    // ok
}
else
{
    // error
}


As for why the behavior has changed, that's because the C++ standard has evolved:

From C++03:

If an error occurs, val is unchanged; otherwise it is set to the resulting value.

From C++0x (well.. from the last draft I have access to):

The numeric value to be stored can be one of:

  • zero, if the conversion function fails to convert the entire field.
  • the most positive (or negative) representable value, if the field to be converted to a signed integer type represents a value too large positive (or negative) to be represented in val.
  • the most positive representable value, if the field to be converted to an unsigned integer type represents a value that cannot be represented in val.
  • the converted value, otherwise.


The C++ standard has changed in the required behaviour for this case. The requirements can be found in [lib.facet.num.get.virtuals] (22.2.2.1.2 in C++03, 22.4.2.1.2 in C++0x)

In C++03, the requirement is that the old value is unchanged in case of an error.
In C++0x, the requirement is that the value 0 is stored in case of a conversion error.


If you want a failed stream-in not to affect your variable and you don't want it to put the stream into a failed state, then stream in to a string, parse the string into a temporary and if all that succeeds, continue.

You can parse the string into a temporary using istringstream.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜