当前位置: 首页 > 知识库问答 >
问题:

cin 在溢出整型时出现意外行为

寿浩言
2023-03-14

所有,我这里有一些无法解释行为的代码。它贴在下面。我看了为什么整数溢出会导致C iostream的错误?,但它并没有真正回答我的问题。

#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(溢出整数1),则第一个输出将显示“x的值=-2147483648”,第二个输出将表示“x的数值=214748364”。cin。fail()也将返回true。cin对输入做了什么?我想如果cin。如果fail()为true,则x的值应不受影响。如果不受影响,我希望x的值会像正常一样溢出(就像scanf一样)。cin怎么了?为什么要将该值限制为整数最大值?

提前感谢!

共有2个答案

施子民
2023-03-14

>

  • 您的scanf:溢出C中有符号整数类型的行为是未定义的。推测幕后发生的事情是毫无意义的。“正常溢出”特别没有意义。

    您的cin:在C 03之前,x如果不能适应输入,则不会更改。因此,后续cout的行为将是未定义的,因为您将读回未初始化的变量。从C 03开始,x如果超出其范围,则在其最大(或最小)值处设置上限(或下限)。这就是你的第二种情况。

  • 白彦
    2023-03-14

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

    例如:

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

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

    对于<code>运算符

    转换就像是由以下代码片段执行的(使用与前面代码片段相同的符号):

    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);
    
     类似资料:
    • 虚拟机安装:Ubuntu 12.04(x86) 什么是整数溢出? 存储大于最大支持值的值称为整数溢出。整数溢出本身不会导致任意代码执行,但整数溢出可能会导致堆栈溢出或堆溢出,这可能导致任意代码执行。在这篇文章中,我将仅谈论整数溢出导致堆栈溢出,整数溢出导致堆溢出将在后面的单独的帖子中讨论。 数据类型大小及范围: 当我们试图存储一个大于最大支持值的值时,我们的值会被包装 。例如,当我们尝试将存储到带

    • 问题内容: 我正在使用哈希函数,该函数返回一个。 然后,我想将其存储在仅支持(带符号的64位)的PostgreSQL中。 因为我对数字本身不感兴趣,但对二进制值(因为我将其用作检测唯一性的ID(我的值集为〜1000个值,一个64位的哈希值对我来说足够了)),我想通过“只是”更改类型将其转换为。 如何以一种使编译器满意的方式做到这一点? 问题答案: 您可以简单地使用类型转换: 输出: 转换为始终成功

    • 给定一个非空二叉树,求最大路径和。 对于这个问题,路径被定义为沿着父子连接从某个开始节点到树中任何节点的任何节点序列。路径必须包含至少一个节点,并且不需要经过根。 和 = 42 我是初学者。如果可能的话,只帮助cpp,我对逻辑非常清楚。我想知道我的数据类型知识有什么问题? 下面的maxpathsum函数必须返回int值,我使用long-long只是为了避免整数溢出,然后在返回最终答案之前进行类型转

    • 本文向大家介绍C#整数溢出,包括了C#整数溢出的使用技巧和注意事项,需要的朋友参考一下 示例 整数可以存储的最大容量。而当您超过该限制时,它将循环回到负面。对于int,它是2147483647 对于超出此范围的所有整数,请使用System.Numerics数据类型为BigInteger的名称空间。检查下面的链接以获取更多信息https://msdn.microsoft.com/zh-cn/libr

    • 我正在使用getline(cin.getline())从cin中获取一个字符串,并发现一个特殊情况的问题。如果用户输入的字符比stream size参数多(在本例中为50),cin缓冲区会保存它们并将它们放入下一个cin调用中。如果我使用cin.clear()和cin.ignore(),并且用户输入的字符比stream size参数少,那么程序会等待用户再次按Enter,然后继续运行。所以我使用s

    • 问题内容: 运行这部分代码时出现错误。尝试了一些现有的解决方案,但都没有帮助 我总是收到这个错误 问题答案: 这意味着在完成所有代码块之前,已到达源代码的末尾。代码块以类似如下的语句开头,然后至少需要一行包含其中应包含的代码的行。 好像您在ipython控制台中逐行执行程序。这适用于单个语句,例如for循环,但不适用于代码块。请参见以下示例: 为避免此错误,您必须将整个代码块作为单个输入输入: