我必须编写一个程序,该程序接受一个包含以下以空格分隔的值的输入: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
这里到底发生了什么?
答案 0 :(得分:2)
istream::operator>>
function调用std::num_get::get
function,后者调用std::num_get::do_get
函数。
do_get
函数分三个阶段进行解析,对于stage 3 (conversion and storage),有以下注意事项:
如果转换函数产生的正值太大而无法容纳
v
类型,则最正的可表示值存储在v
[注意:v
是目标变量]
这说明了该值会发生什么,以及为什么您为2147483647
得到long
。我们还可以这样说,您正在使用long
大小仍为32位的系统。
然后继续进行第3阶段的注释列表:
无论如何,如果转换功能失败,
std::ios_base::failbit
将分配给err
这说明了其余值会发生什么。设置failbit
后,您将无法清除输入流中的内容。
此外,如果我们回到operator>>
reference,我们会看到对于C ++ 98和C ++ 03
如果提取失败...值将保持不变,并设置
failbit
。
对于C ++ 11和更高版本
如果提取失败,则将零写入值
由于设置failbit
之后的变量不为零,因此我们可以推断出您正在使用C ++ 11之前的编译器来构建它。您打印的值是未初始化的内容,它们是不确定的。甚至阅读不确定的内容也会导致undefined behavior。
答案 1 :(得分:0)
您输入的长号超出了MAX_LONG =2147483647。因此在这种情况下,这是溢出问题。