简体   繁体   English

cin溢出时来自cin的异常行为

[英]Unexpected behavior from cin when overflowing int

All, I've got some code here that I can't explain the behavior of. 所有,这里有一些我无法解释其行为的代码。 It is posted below. 它发布在下面。 I looked at Why does integer overflow cause errors with C++ iostreams? 我查看了为什么整数溢出会导致C ++ iostream错误? , but it doesn't really answer my question. ,但并不能真正回答我的问题。

#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
    int x;
    scanf("%d", &x);
    cout << "Value of x = " << x << endl;
    cin >> x;
    cout << "Failure Detected = " << cin.fail() << endl;
    cout << "Value of x = " << x << endl;
    return 0;
}

So, what I expect this code to do is read in an integer, print out the value of that integer, read in another integer (into the same variable), and print out that integer. 因此,我期望此代码执行的操作是读入一个整数,打印出该整数的值,读入另一个整数(读入同一变量),然后打印出该整数。 If I enter input of 7 and 2, then it works as expected. 如果输入7和2的输入,那么它将按预期工作。 However, if I enter 2^31 (overflow int by one) for both the first and second input, then the first output will say "Value of x = -2147483648" and the second output will say "Value of x = 2147483647". 但是,如果我为第一个和第二个输入都输入2 ^ 31(溢出int乘以1),则第一个输出将显示“ x的值= -2147483648”,第二个输出将显示“ x的值= 2147483647”。 cin.fail() will also return true. cin.fail()也将返回true。 What is cin doing to the input? cin对输入做了什么? I thought that if cin.fail() was true, the value of x should be left unaffected. 我以为如果cin.fail()为true,则x的值应保持不变。 If not left unaffected, I would expect the value of x to overflow as normal (like scanf does). 如果不受影响,我希望x的值像正常情况一样溢出(就像scanf一样)。 What's going on with cin here? cin这是怎么回事? Why is it capping the value at integer max value? 为什么将值限制为整数最大值?

Thanks in advance! 提前致谢!

In C++98 the variable was unchanged when input failed. 在C ++ 98中,输入失败时变量未更改。 This was a disadvantage if you try to input to an uninitialized variable. 如果您尝试输入一个未初始化的变量,这是一个缺点。

For example: 例如:

int a;
cin >> a;
cout << a;    // UB if input failed!

In later standards the variable will be set to the largest or smallest value possible when the input is outside of that range. 在以后的标准中,当输入超出该范围时,变量将设置为可能的最大值或最小值。


For operator>>(int& val) the standard says [istream.formatted.arithmetic]: 对于operator>>(int& val) ,标准说[istream.formatted.arithmetic]:

The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment): 转换似乎由以下代码片段执行(使用与前面的代码片段相同的表示法):

typedef num_get<charT,istreambuf_iterator<charT,traits> > numget;
iostate err = ios_base::goodbit;
long lval;
use_facet<numget>(loc).get(*this, 0, *this, err, lval);
if (lval < numeric_limits<int>::min()) {
  err |= ios_base::failbit;
  val = numeric_limits<int>::min();
} else if (numeric_limits<int>::max() < lval) {
  err |= ios_base::failbit;
  val = numeric_limits<int>::max();
} else
  val = static_cast<int>(lval);
setstate(err);
  1. Your scanf : The behaviour on overflowing a signed integral type in C++ is undefined . 您的scanf :C ++中溢出有符号整数类型的行为是不确定的 It's rather pointless to speculate on what is happening under the hood. 推测幕后发生的事情是毫无意义的。 "Overflow as normal" is particularly meaningless. “正常溢出”尤其没有意义。

  2. Your cin : Pre C++03, the x would not have been changed if it could not accommodate the input. 您的cin :C ++ 03之前的版本,如果x无法容纳输入,则不会更改x So the behaviour of a subsequent cout would have been undefined since you'd be reading back an uninitialised variable. 因此,后续cout的行为将是不确定的,因为您将回读未初始化的变量。 From C++03 onwards, x is capped (or floored) at it largest (or smallest) value if its range would be exceeded. 从C ++ 03开始,如果超出x的范围,则将x为最大(或最小)值。 That is what is happening in your second case. 那就是第二种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM