【问题标题】:Why is cin.failbit always set even when input is valid?为什么即使输入有效,cin.failbit 也总是设置?
【发布时间】:2019-05-30 11:01:33
【问题描述】:

我正在尝试编写一个程序,要求使用cin.getline() 输入一个字符数组,如果给定的输入大于数组长度,则数组得到扩展。

我使用cin.failbit 来查看用户的输入是否太长。但一切都不顺利。所以调试后发现问题出在failbit

所以我写了一个简单的程序来看看它有什么问题,结果发现cin.failbit always 在 if 语句中即使在输入时也会返回 true似乎有效。

int main () {
    char name[256];

    std::cout << "Enter your name: ";
    std::cin.getline (name,256, '\n');

    std::cout << "characters read: " << std::cin.gcount() << std::endl;
    if (std::cin.failbit){
        std::cin.clear();
        std::cout << "failed\n";
    }
} 

例如,当输入为“qwer”时,程序输出已读取 5 个字符(cin.gcount),所以应该没问题,但它也输出“fail”,表示设置了失败位标志。但我认为不应该出现在这种情况下。

program output here

那么谁能解释为什么failbit 似乎被永久设置了?

我们将不胜感激任何帮助

【问题讨论】:

  • @fran 请不要回答 cmets。
  • FWIW 你可以使用if (!std::cin) 来检查流是否处于故障状态。
  • 我错了,没有failbit成员函数。它正在检查failbit bit mask 的值是否不为零。我在想fail() 成员函数。 std::cin.failbit 是一个常量,表示哪个位表示失败状态,它不检查流的状态。
  • 感谢您的回复。我考虑使用 cin.fail() 或 !cin 但当用户的输入长于数组的 len 时,它们不会被调用。用户的输入刚刚被剪切,所有超过数组大小的字符都保留在缓冲区中(至少这是我观察到的)
  • @keptt 不,failbit 不是状态意义上的标志。它指示哪个位与该标志相关联。它不能被设置或清除,它是一个常数。短语“failbit 标志”表示“位掩码 failbit 指示的位”。

标签: c++ arrays cin getline


【解决方案1】:

std::cin.failbit 是一个常量,指示哪个错误位表示流失败。它不是流的当前状态的指示。要检查该位是否已设置,请改用成员函数 std::cin.fail()

但是,如果由于到达流的末尾而导致流读取失败,fail() 将返回 false,从而使您相信它已成功。首选std::cin.good()检查最后一次操作是否成功。

【讨论】:

  • 我很欣赏这个答案,但对我来说,关于故障位的部分只会干扰 getline 描述link 此处的第 4 个块指出:“如果函数未提取字符,或者如果分隔符,则设置故障位标志一旦 (n-1) 个字符已经写入 s",就找不到。所以对我来说这很混乱
  • @keptt 错误状态存储在位集中。 failbit 是一个常数,指示哪些位代表失败。例如,它的值可能是常量8,表示第 4 位表示失败。在这种情况下,您的 if 本质上将是 if(8) 并且不考虑您的流的当前状态。使用failbit 的示例可能是std::cin.rdstate() &amp; std::ios_base::failbit,以查看failbitrdstate() 返回的位集中是否为1
  • 谢谢,我想我现在明白了。我试图按照您的建议采取行动并使用 cin.good() - 到目前为止效果很好。不要太烦人,但你介意我问一下如何处理故障位吗?如果它是一个常量,那么它应该具有某种默认值含义,如果我输入 smth 之类的 - if(cin.failbit == default_value) 这意味着没有检测到可以触发故障位的错误并且一切都很好。是这样的吗?
  • @keptt No. failbitcin 的状态无关。想象一下它是一个全局常量(因为它就是这样)。您无法从中提取任何有用的信息,它是一个数字,并且在程序的整个生命周期中始终是该数字。想象一下,无论你在哪里看到failbit,它都只是说4,或者16,或者它具有的任何值。它在程序的生命周期内不能改变。它用作位掩码来帮助您解释rdstate() 返回的值。 std::cin.failbit 编译的事实具有误导性。 failbitstatic constexpr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多