【问题标题】:Why is failbit set when I enter EOF?为什么输入EOF时会设置failbit?
【发布时间】:2022-01-15 06:25:40
【问题描述】:

我目前正在学习while (cin >> num) 的工作原理,我发现有两个步骤。 第一个是 operator>> 函数返回一个带有错误状态的 istream 对象,第二个是 bool 转换器,将 istream 对象转换为 bool 取决于它的状态。

但我发现在 bool convert 函数中,只有在设置了 failbit 或 badbit 时它才会返回 0,这让我感到困惑。并且 operator>> 函数如果读取 EOF 将设置 eofbit。

布尔转换函数:https://www.cplusplus.com/reference/ios/ios/operator_bool/

操作员>>函数:https://www.cplusplus.com/reference/istream/istream/operator%3E%3E/

在这种情况下,在我输入 EOF 后,布尔转换器应该返回 1,因为未设置故障位和坏位。

因此,我使用下面的程序来检查输入 EOF 后错误位实际发生了什么。 我发现进入EOF后failbit会被设置!!

所以我想知道是否有人可以帮助我理解为什么要设置故障位?

#include <iostream>

using namespace std;

int main()
{
    int num;
    cin >> num;
    cout << cin.eof() << " " << cin.fail() << " " << cin.bad() << endl;
    return 0;
}

输入:^Z(在使用 qt creator 的 windows 上,非 qt c++ 项目) 输出:1 1 0

输入:^D(在使用 qt creator 的 windows 上,非 qt c++ 项目) 输出:0 1 0

【问题讨论】:

    标签: c++ linux qt operating-system iostream


    【解决方案1】:

    eofbit 在读取操作在将数据读取到流缓冲区时遇到 EOF 时设置。数据尚未处理。

    failbit 在请求的数据无法从缓冲区中提取时设置,例如在读取带有operator&gt;&gt; 的整数时。在等待数字到达时,可能会发生 EOF。仅eofbit 不足以进入错误状态,因为缓冲区中可能有可用数据。

    例如,假设使用了while (cin &gt;&gt; num) 循环并且用户输入123&lt;Ctrl-Z&gt;

    • 在第一次迭代中,operator&gt;&gt;123 读入缓冲区,然后遇到 Ctrl-Z,因此它设置了eofbit 并停止读取。然后将123 从缓冲区中提取到num 中,然后操作员退出。此时,流尚未处于错误状态。当while 评估流的bool 转换时,它返回true,允许输入while 正文,以便处理num

    • 在下一次迭代中,operator&gt;&gt; 看到 eofbit 已设置,从而阻止进一步阅读。缓冲区中没有任何内容可提取到num,因此操作员设置failbit 并退出。流现在处于错误状态。当while 评估流的bool 转换时,它返回false,打破while 循环。

    【讨论】:

    • 非常感谢!!你的解释很清楚!!我一直认为是因为EOF终止了程序。不知道char或者double也可以有同样的效果~
    • BTW 你知道 Ctrl+D 在 windows 中是什么意思吗?如果我按 Crtl+D 它只会设置故障位,而我在互联网上所能找到的只是谈论 Crtl+D 在基于 unix 的操作系统中所做的事情。
    • @Benasking7124 Ctrl+D 在 Windows cmd 窗口中实际上并没有做任何事情,它被视为控制字符 (^D)。它在其他应用程序的上下文中执行某些操作(即,在资源管理器中,它将选定的文件移动到回收站)
    • 哦,我明白了!这是因为字符^D不被触发failbit的int类型接受吗?(就像我在int变量中输入“abc”一样)不是因为Crtl+D有一些特殊含义
    • @Benasking7124 是的,完全正确
    【解决方案2】:

    如果EOF是第一个输入,operator&gt;&gt;读取整数失败,所以流进入fail()状态。

    如果您在 Ctrl-Z 之前至少键入一位数字,则读取该数字并且输入成功。

    【讨论】:

    • 谢谢你的解释~
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2017-03-11
    • 2013-01-13
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多