2

考虑

float num;
cin >> num;

是否明确定义了此代码可以使用多少个输入字符。我对输入流的指定精度可能比类型可以表示num的精度高得多的情况特别感兴趣。float因此,在这种情况下,代码是否会读取所有代码(直到但不包括下一个非数字输入)或仅读取float.

4

3 回答 3

4

输入在 std::num_get 22.4.2.1.2 中定义:

第 3 阶段:第 2 阶段(字段)中累积的字符序列通过标头中声明的函数之一的规则转换为数值:

— 对于有符号整数值,函数 strtoll。

— 对于无符号整数值,函数 strtoull。

— 对于浮点值,函数 strtold。

要存储的数值可以是以下之一:

— 零,如果转换函数无法转换整个字段。ios_base::failbit 分配给 err。

— 最正的可表示值,如果该字段表示的值太大而无法用 val 表示。ios_base::failbit 分配给 err。

— 如果字段表示的值太大而无法用 val 表示,则为无符号整数类型的最负可表示值或零。ios_base::failbit 分配给 err。

因此,流将消耗所有有效的数字模式(即使在溢出之后),并且将相应地设置状态。

于 2014-03-11T03:28:57.197 回答
3

请参阅std::istream::operator>> docs中有关“(1) 算术类型”的信息。这使用num_get::get()和文档的相关部分说明“只要一个字符不能成为有效数字表达式的一部分,该函数就会停止从序列中读取字符”。

因此,从文档看来,所有可用的数字都将被读取,但如果浮点类型太“窄”,则不会全部使用它们。

于 2014-03-11T03:34:47.610 回答
1

您可以通过一个小实验来测试其中的一部分:

#include <iostream>

int main(void) {
    float f;
    std::string s;

    std::cin >> f;
    std::cin >> s;

    std::cout << f << std::endl;
    std::cout << s << std::endl;

    return 0;
}

然后编译:

$ g++ --version
g++ (GCC) 4.8.2
...

$ g++ -std=c++11 -pedantic -Wextra -Wall ./fltest.cpp

并使用您知道的位数多于 a 的输入运行float

$ echo '3.1415926535 foo' | ./a.out
3.14159
foo

因此,似乎多余的额外精度被丢弃了(单精度浮点数的精度略高于 7 位十进制数字。

您可以使用输入和输出精度来查看它们的效果,例如:

std::cin.precision(7);

在行之前,std::cin >> f;或者说:

std::cout.precision(10);

行前std::cout << f;

于 2014-03-11T03:21:25.717 回答