溢出 int 时 cin 的意外行为

2023-12-29

所有,我这里有一些代码我无法解释其行为。下面发布了。我在看为什么整数溢出会导致 C++ iostream 错误? https://stackoverflow.com/questions/3582509/why-does-integer-overflow-cause-errors-with-c-iostreams,但它并没有真正回答我的问题。

#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;
}

因此,我希望这段代码要做的是读入一个整数,打印出该整数的值,读入另一个整数(进入同一个变量),然后打印出该整数。如果我输入 7 和 2,那么它会按预期工作。但是,如果我为第一个和第二个输入都输入 2^31(int 溢出 1),则第一个输出将显示“Value of x = -2147483648”,第二个输出将显示“Value of x = 2147483647”。 cin.fail() 也会返回 true。 cin 对输入做了什么?我认为如果 cin.fail() 为 true,则 x 的值应该不受影响。如果不受影响,我预计 x 的值会正常溢出(就像 scanf 那样)。 cin 这是怎么回事?为什么它将值限制在整数最大值?

提前致谢!


在 C++98 中,当输入失败时,变量保持不变。如果您尝试输入未初始化的变量,这是一个缺点。

例如:

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

在后来的标准中,当输入超出该范围时,变量将被设置为可能的最大或最小值。


For operator>>(int& val)标准说[istream.formatted.arithmetic]:

转换的发生就好像由以下代码片段执行一样(使用与 前面的代码片段):

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);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

溢出 int 时 cin 的意外行为 的相关文章

随机推荐