我必须编写一个程序,它接受由以下空格分隔的值组成的输入:分别是 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 数字大于 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)有这样的注释:
If the conversion function results in a positive value too large to fit in the type of
v
, the most positive representable value is stored inv
[注意:v
是目标变量]
这解释了该值会发生什么,以及为什么您会得到 long
值的 2147483647
。由此我们还可以看出,您所在的系统中 long
的大小仍然是 32 位。
第三阶段的注释列表继续:
In any case, if the conversion function fails
std::ios_base::failbit
is assigned toerr
这解释了其余值会发生什么情况。一旦设置了 failbit
,您就无法从输入流中读取更多内容,直到清除状态。
此外,如果我们回到operator>>
reference我们看到对于 C++98 和 C++03
If extraction fails ... value is left unmodified and
failbit
is set.
对于 C++11 及更高版本
If extraction fails, zero is written to value
由于设置 failbit
后的变量不为零,因此我们可以推断您正在使用 C++11 之前的编译器构建此变量。您打印的值是未初始化的内容,不确定。甚至读取不确定的内容也会导致 undefined behavior .
关于c++ - 使用 cin 和 cout 时无法正确打印字符变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54714661/