当istream读取失败时存储的值 [英] Value stored when istream read fails

查看:149
本文介绍了当istream读取失败时存储的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例代码:

  #include< iostream& 

int main()
{
int x = 5;
std :: cin>> X;
std :: cout<< x < '\\\
';
}

一个特定实现,发生以下行为:




  • 输入: 6 ;输出 6

  • 输入: a 输出: 0

  • 输入:(文件结束)输出 5

  • 输入:(空格后跟文件结尾)输出 5



cin>>如果未能将文本转换为int,则 0 分配给 x 但如果失败是由于文件结束,则不会分配 0



这是正确的行为?如果没有,根据C ++标准,什么是正确的行为?



我从以前讨论的所有情况下应该写 0 自从C ++ 11,但我找不到任何使用搜索功能;

解决方案

根据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段,如果流的标志不是<$ c,则 sentry 将转换为 false $ c> std :: ios_base :: goodbit 。也就是说,如果遇到失败的happend或EOF, sentry 将转换为 false 。结果,当跳过空格后达到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


所以,观察到的行为是正确的。



在所有情况下保持不变。认为理想的是将错误分开并用值表示应该表示哪个值。关于如何改变行为的讨论持续了相当长的时间,实际上是相当有争议的。



如果在尝试之前达到EOF,那么值不会改变转换可能被认为是错误。我不记得在讨论改变时要考虑的情况。


Sample code:

#include <iostream>

int main()
{
    int x = 5;
    std::cin >> x;
    std::cout << x << '\n';
}

On one particular implementation the following behaviour occurs:

  • Input: 6; output 6
  • Input: a; output: 0
  • Input: (end-of-file); output 5
  • Input: (whitespace followed by end-of-file); output 5

So, on failure, the cin >> x is assigning 0 to x if it was a failure to convert text to int; but it is not assigning 0 if the failure was due to end-of-file.

Is this correct behaviour? If not, what is the correct behaviour, according to the C++ Standard?

I have a recollection from previously discussing on SO that all cases should write 0 since C++11, but I could not find anything using the search feature; and the iostreams section of the C++ standard is pretty heavy going.

解决方案

According to 27.7.2.2.1 [istream.formatted.reqmts] paragraph 1 the first things for the formatted input function is to construct an std::istream::senty object. Further processing depends on whether this object converts to true or false: nothing happens to the value if the sentry converts to false.

According to 27.7.2.1.3 [istream::sentry] paragraphs 5 and 7 the sentry will convert to false if the stream's flags are not std::ios_base::goodbit. That is, if either a failure happend or EOF is reached the sentry will convert to false. As a result, the value stays at 5 when EOF is reached after skipping whitespace, assuming std::ios_base::skipws is set. Unsetting std::ios_base::skipws should result in the value becoming 0 if there is, at least, one space.

Once parsing is actually done, the applies logic is defined in 22.4.2.1.2 [facet.num.get.virtuals] paragraph 3, Stage 3. The key section on the affected value is

...

The numeric value to be stored can be one of:

— zero, if the conversion function fails to convert the entire field. ios_base::failbit is assigned to err.

— the most positive representable value, if the field represents a value too large positive to be represented in val. ios_base::failbit is assigned to err.

— the most negative representable value or zero for an unsigned integer type, if the field represents a value too large negative to be represented in val. ios_base::failbit is assigned to err.

— the converted value, otherwise.

The resultant numeric value is stored in val.

So, the observed behavior is correct.

With pre-C++11 the value was left unchanged in all cases. It was considered desirable to tell errors apart and indicate with the value which value should be represented. The discussions on how to change the behavior went on for a rather long time and were actually quite contentious.

That the value isn't changed if EOF is reached before attempting a conversion may be considered an error. I don't recall that case to be considered while the change was discussed.

这篇关于当istream读取失败时存储的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆