首页 文章

如何在while循环中评估“std :: cin >> value”?

提问于
浏览
5

目前我正在自学C Primer 5th . 这是我不确定的事情 . (我在F.A.Q找不到确切的相关问题) .

考虑这个while循环:

while(std::cin>>value){...}  \\value here was defined as int.

教科书上写道:

该表达式从标准输入中读取下一个数字,并将该数字存储在值中 . 输入运算符(第1.2节,第8页)返回其左操作数,在本例中为std :: cin . 因此,这个条件测试std :: cin . 当我们使用istream作为条件时,效果是测试流的状态 . 如果流是有效的 - 也就是说,如果流没有遇到错误 - 则测试成功 .

我的问题是: std::cin 首先将输入读入 value 然后测试 std::cin 的验证,或首先测试 std::cin 然后决定是否读入'value'?我很困惑什么时候"returns its left operand" .

6 回答

  • 12

    请记住,您的代码相当于:

    while (std::cin.operator>>(value)) { }
    

    要么:

    while (1) {
        std::cin >> value ;
        if (!std::cin) break ;
    }
    

    在测试 std::cin 之前,"code"总是尝试从 std::cin 读入 value .

    我们来看看报价:

    [...]输入运算符(第1.2节,第8页)返回其左操作数,在本例中为std :: cin . [...]

    这仅表示 std::cin.operator>>(value) 返回 std::cin .

    因此,这个条件测试std :: cin . 当我们使用istream作为条件时,效果是测试流的状态 . 如果流是有效的 - 也就是说,如果流没有遇到错误 - 则测试成功 .

    教科书所说的是在尝试读取 std::cinvalue 之间的整数后, >> 运算符返回 std::cin . 如果 std::cin 在读取 value 后处于良好状态,则测试通过,否则失败 .


    一些额外的细节:

    当您执行 std::cin >> value 时,基本上调用 istream::operator>>(int&) ,并且是的,该方法内部有一个测试:如果测试通过,则 std::cin 的内部状态设置为ios_base::goodbit,如果失败,则内部状态设置为错误标志的on (eofbitfailbitbadbit) .

    根据exception mask for std::cin ,如果内部测试失败,则异常may be thrown .

    从你的报价:

    当我们使用istream作为条件时,效果是测试流的状态 .

    这基本上意味着:

    if (std::cin) { }
    

    equivalent到:

    if (!std::cin.fail()) { }
    

    std::cin.fail() 检查 failbitbadbit . 这意味着 while (std::cin >> value) { } 不会测试 eofbit 标志,只有在输入无法转换为整数值时才会失败 .

  • 3

    首先将std :: cin读入值读入然后测试std :: cin的验证,或先测试std :: cin然后决定是否读入'value'

    cin 首先尝试从标准输入读取 int ,如果 cin 处于良好状态:如果失败,则将流设置为错误状态;无论操作完成,它都将返回流本身(即"left operand" - cin ),这将允许您检查成功或失败 .

    如果您想先显式测试流的有效性,然后尝试读取该值,您将拥有:

    while (cin && cin >> value)
    

    但是's pretty redundant, since, as I'告诉过你, cin 如果已经处于不良状态,甚至不会尝试阅读 value .

  • 2

    有两个测试 .

    第一个测试是while语句的条件

    while(std::cin>>value){...}
    

    此条件测试调用操作符函数 operator >> 的结果

    第二次测试是操作员的一个条件 . 如果流 std::cin 的状态良好,则该函数尝试从字符串中读取整数 . 否则,它返回 std::cin ,当前错误状态为 std::cin .

    在while条件下有一个表达式

    std::cin>>value
    

    必须评估此表达式 . 所以这个条件测试了 operator >> 的调用结果 .

    运算符的结果是流 std::cin 但是由于运算符,它可以在上下文中转换为bool值

    explicit operator bool() const;
    

    它返回流的状态

    !fail().
    
  • 0

    我假设你的“ Value ”是例如一个int

    • 流尝试读取输入直到下一个空格 .

    • 如果找到eof ... - >那么状态将被设置为“eof”,>>将返回流并且流的布尔值评估将返回false

    • 如果在读取过程中发生错误(例如I / O),状态将设置为“bad”,>>将返回流并且流的布尔值评估将返回false

    • 如果有空格已经找到,然后将尝试从读取字符到int(上述假设)的转换 . 如果失败(因为读取输入是例如:“xx”而不是数字),则流的状态将设置为“失败” . >>将返回流,并且流的布尔值评估将返回false

    • 如果我们在链条上这么远,找不到eof,没有发生IO错误(或其他),并且字符 - > int转换成功 . >>将返回流,并且流的布尔值评估将返回true .

    而你的“ Value ”将包含适当的 Value

  • 1

    大概你不会对简单的函数调用产生任何困惑:

    SomeReturnType some_function(int&);
    while (some_function(value)) { ... }
    

    上面的代码将重复调用 some_function ,直到函数调用的返回值(解释为布尔值)为 false . 为循环中的每个步骤调用该函数 . 函数是否更改 value 的值取决于函数 . 它当然可以这样做,并且可能会这样做(但这对于该功能的设计者来说是一个问题) .

    循环 while (std::cin>>value) {...} 完全等同于 while (std::cin.operator>>(value)) {...} . 这只是对成员函数 std::stream::operator>>(int&) 的函数调用 .

  • 1

    操作员首先读取值,然后返回对象的引用 . while 语句首先调用该运算符,然后第二次测试返回的值 .

相关问题