示例代码:
#include <iostream>
int main()
{
int x = 5;
std::cin >> x;
std::cout << x << '\n';
}
在one particular implementation上,会发生以下行为:
6
;输出6
a
;输出:0
5
5
因此,如果失败,cin >> x
会将0
分配给x
,如果它无法将文本转换为int;但如果失败是由于文件结束,则不会分配0
。
这是正确的行为吗?如果没有,根据C ++标准,正确的行为是什么?
我从之前的SO讨论中回忆起所有案例都应该从C ++ 11开始编写0
,但我找不到任何使用搜索功能的内容。而且C ++标准的iostreams部分非常重要。
答案 0 :(得分:3)
是的,这是自C ++ 11以来的正确行为。
您所看到的差异在于写入零&#34;当提取失败&#34;时,如果已经在流上设置了EOF,则甚至不尝试提取...所以没有任何反应。< / p>
答案 1 :(得分:1)
根据27.7.2.2.1 [istream.formatted.reqmts]第1段,格式化输入函数的第一件事是构造一个std::istream::senty
对象。进一步处理取决于此对象是转换为true
还是false
:如果sentry
转换为false
,则该值不会发生任何变化。
根据27.7.2.1.3 [istream :: sentry]第5和第7段,如果流的标志不是sentry
,false
将转换为std::ios_base::goodbit
。也就是说,如果发生失败或EOF,sentry
将转换为false
。因此,如果设置了value
,则在跳过空格后达到EOF时5
会保持std::ios_base::skipws
。如果至少有一个空格,则取消设置std::ios_base::skipws
会导致值变为0
。
实际完成解析后,应用逻辑在22.4.2.1.2 [facet.num.get.virtuals]第3段第3阶段中定义。受影响值的关键部分是
...
要存储的数值可以是以下之一:
- 零,如果转换函数无法转换整个字段。
ios_base::failbit
被分配到err
。- 最积极的可表示值,如果该字段表示的值太大而无法在
val
中表示。ios_base::failbit
被分配到err
。- 无符号整数类型的最负值可表示值或零,如果该字段表示的值太大而无法在
val
中表示。ios_base::failbit
被分配到err
。- 转换后的值,否则。
结果数值存储在
中val
。
因此,观察到的行为是正确的。
对于预C ++ 11,所有情况下的值都保持不变。认为分开错误并用值表示应该表示哪个值是合乎需要的。关于如何改变行为的讨论持续了相当长的时间,实际上很有争议。
如果在尝试转换之前达到EOF,则该值不会被更改,这可能会被视为错误。我不记得在讨论变更时要考虑的情况。