【问题标题】:Standard input state after error condition错误条件后的标准输入状态
【发布时间】:2021-12-04 16:12:53
【问题描述】:

以下代码 sn-p 取自C++ Iostreams Handbook by Steve Teale。它建议在无限循环中调用 cin,以便不断提示用户输入正确的输入,并且只有在输入正确的输入时我们才会退出循环。

这段代码 sn-p 可以正常工作,但我对 if(cin){...} 语句感到困惑。我会期待像if(!cin.fail()){...} 这样的东西。

#include <limits.h>
#include <iostream>
using namespace std;

int main()
{
  int n;
  cin.unsetf(ios::skipws);
  // turn off whitespece skipping
  
  cout << "Enter a value for n, followed by [Enter]: " << flush;
  
  for(;;) {
    cin >> n;
    if(cin) { //cin is in good state; input was ok
      cin.ignore(INT_MAX, '\n');
                // flush away the unwanted
                // newline character
      break;
    }

    // Poster's comment (not from the author)
    // In this section of the code cin has evaluated to false
    //
    cin.clear(); // clear the error state
    cin.ignore(INT_MAX, '\n');
                 // get rid of garbage characters
    cout << "That was no good, try again: " << flush;
  }

  return 0;
}

Q) 发生故障时 cin 如何评估为 false(即零或空值)?

cin 是一个对象,而不是可以设置为 null 的指针。此外,在 cin 计算结果为 false 的代码部分中,我们仍然可以调用成员函数,例如 clearignore

【问题讨论】:

  • 他们只是颠倒了逻辑。该循环是一个持续的读取循环,只有在接收到良好的输入时才会中断。这是一个很好的方法。注意:cin.ignore(INT_MAX, '\n'); 会在正确输入后清理,以防在读取整数 n 后出现任何无关字符,例如"4 and other stuff"。这也是一种很好的做法。
  • @DavidC.Rankin cin 如何评估为 False?请对此有所了解。
  • 任何时候出现错误(例如badbitfailbit 设置),无论您检查if (cin) 还是if (cin.good()),流状态都会评估false。在这两种情况下,如果设置了错误位,则条件为false
  • @DavidC.Rankin 是否有一些运算符重载魔法在起作用,允许 cin 在布尔上下文中使用(在if 语句中)?似乎有什么东西比我的眼睛还多。请给我一些链接,我会相应地启发自己。
  • std::basic_ios::operator boolstd::ios_base::iostate。它将在goodbiteofbit 上测试true,否则false

标签: c++ iostream


【解决方案1】:

您观察到的是继承和隐式转换的结果。更具体地说,std::cin 有一个 operator bool(),它将流的状态转换为布尔值,并且该运算符返回 !fail()

std::cin是标准库提供的全局std::basic_istreambasic_istream继承自std::basic_iosstd::basic_ios定义了函数operator bool()

继承链是:

std::ios_base <-- std::basic_ios <-- std::basic_istream

您可能会发现this webpage 底部的表格有助于将operator bool() 与流的其他状态检查功能和流的不同状态标志进行比较。

【讨论】:

    猜你喜欢
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2018-10-21
    • 2014-07-22
    • 1970-01-01
    • 2013-01-11
    相关资源
    最近更新 更多