使用cin和cout时无法正确打印字符变量

时间:2019-02-15 17:53:04

标签: c++ input output long-integer

我必须编写一个程序,该程序接受一个包含以下以空格分隔的值的输入: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

这里到底发生了什么?

2 个答案:

答案 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。因此在这种情况下,这是溢出问题。