【问题标题】:if(!getline(std::cin, str1)) break; what does this condition check?if(!getline(std::cin, str1)) 中断;这个条件检查什么?
【发布时间】:2015-05-22 00:39:22
【问题描述】:

我有这个代码:

 while (true){
 std::string cmdline;
 if (!std::getline( std::cin, cmdline )) break;

 std::istringstream cmdstream( cmdline );
 std::string cmd;
 cmdstream >> cmd;
 ...}

如果我省略了!,if 条件会检查什么以及为什么它会以无限循环结束?

【问题讨论】:

    标签: c++ loops getline


    【解决方案1】:

    因为根据: http://www.cplusplus.com/reference/string/string/getline/

    返回参数是输入流,在本例中为 std::cin,因此如果 std::cin 输入为空,则返回为空。

    基本上,用户输入了什么?

    【讨论】:

      【解决方案2】:

      由于 C++ 插入了与零的隐式比较,因此这一行

      if (!std::getline( std::cin, cmdline )) break;
      

      等价于

      if (!std::getline( std::cin, cmdline ) != 0) break;
      

      或者干脆

      if (std::getline( std::cin, cmdline ) == 0) break;
      

      std::getline 返回调用它的流。根据 C++ 库的版本,流将转换为 boolvoid*。当到达输入结束时,转换后的值变为零。这就是当没有额外的输入要读取时循环结束的原因。

      编写相同代码的另一种方法如下:

      std::string cmdline;
      while (std::getline( std::cin, cmdline )) {
          std::istringstream cmdstream( cmdline );
          std::string cmd;
          cmdstream >> cmd;
          ...
      }
      

      这使您可以将结束条件放入循环头中,但代价是在循环外声明 cmdline

      【讨论】:

      • "std::getline 在到达输入末尾时返回零" 它实际上返回流本身,然后使用其布尔转换运算符在上下文中将其转换为boolstd::getline == 0 是编译时错误(在 >=C++11 中),在 C++03 中转换为 void*,然后将其与空指针常量 0 进行比较,使其有效。
      • @0x499602D2 感谢您的评论!我不想在这里涉及小细节,但我想没有办法避免它。
      【解决方案3】:

      std::getline 返回对作为第一个参数传递的流的引用,在您的情况下为 std::cin。这意味着你的

      if (!std::getline( std::cin, cmdline )) break;
      

      等价于

      std::getline( std::cin, cmdline );
      if (!std::cin) break;
      

      最后一行相当于

      if (std::cin.fail()) break;
      

      如果getline 在流中引发failbit 标志,这将打破循环。如果 I/O 错误或流结束条件阻止 getline 读取任何内容,则会发生这种情况。

      【讨论】:

        猜你喜欢
        • 2011-10-12
        • 2020-02-25
        • 2020-03-14
        • 1970-01-01
        • 1970-01-01
        • 2015-11-17
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        相关资源
        最近更新 更多