我必须编写一个程序,该程序接受一个包含以下用空格分隔的值的输入:int,long,char,float和double,然后将这些值中的每一个打印在输出中的新行中。

当我使用printf和scanf编写程序时,它工作得很好。

#include<stdio.h>
int main()
{
    int a;
    long b;
    char c;
    float d;
    double e;
    scanf("%d %ld %c %f %lf", &a, &b, &c, &d, &e);
    printf("%d\n%ld\n%c\n%f\n%lf", a, b, c, d, e);
    return 0;
}

但是,当我使用cin和cout时,发生了一些问题。当长时间输入的数字大于LONG_MAX时,就会发生这种情况。
#include<iostream>
using namespace std;
int main()
{
    int intNumber;
    long longNumber;
    char character;
    float floatNumber;
    double doubleNumber;
    cin>>intNumber>>longNumber>>character>>floatNumber>>doubleNumber;
    cout<<intNumber<<"\n"<<longNumber<<"\n"<<character<<"\n"<<floatNumber<<"\n"<<doubleNumber;
   return 0;
}

例如,如果输入为211916801 97592151379235457 p 19856.992 -5279235.721231465,则第一个程序的输出为
211916801
97592151379235457
p
19856.992
-5279235.721231465

但是,第二个程序是
211916801
2147483647
╠
-1.07374e+08
-9.25596e+61

这里到底发生了什么?

最佳答案

istream::operator>> function调用 std::num_get::get function,后者调用std::num_get::do_get函数。
do_get函数分三个阶段进行解析,对于stage 3 (conversion and storage),有以下注意事项:



[注意:v是目标变量]

这说明了该值会发生什么,以及为什么要为2147483647值获得long。我们也可以这样说,您所使用的系统上long的大小仍为32位。

然后继续进行第3阶段的注释列表:



这就解释了其余值会发生什么。设置failbit后,您必须清除状态才能从输入流中读取更多内容。

此外,如果我们回到 operator>> reference,我们将看到C++ 98和C++ 03



对于C++ 11和更高版本



由于设置了failbit后的变量不为零,因此我们可以推断出您是使用C++ 11之前的编译器构建的。您打印的值是不确定的未初始化内容。甚至阅读不确定的内容也会导致undefined behavior

10-07 19:12
查看更多