【问题标题】:How to read unknown number of inputs?如何读取未知数量的输入?
【发布时间】:2018-11-09 12:21:45
【问题描述】:

我正在使用 C++ Primer 一书学习 C++。

第 1.4.3 节中,给出了以下关于读取未知数量输入的示例代码。

#include <iostream>
int main()
{
  int sum = 0, value = 0;
  // read until end-of-file, calculating a running total of all values read
  while (std::cin >> value)
  sum += value; // equivalent to sum = sum + value
  std::cout << "Sum is: " << sum << std::endl;
  return 0;
}

根据书上的说法,如果我们输入3 4 5 6,输出将是Sum is: 18

但是当我在我的计算机上尝试这个(Windows 10 with MinGW)时,代码并没有结束。即使我输入换行符,它也会继续要求输入。只有当我输入像f 这样的非整数输入时它才有效。


这是预期的吗?如果是,是否有任何代码在输入换行符后停止?

我对 c++ 很陌生,而且我已经学过 python,所以这么早被卡住是很令人沮丧的。


感谢和问候。

【问题讨论】:

  • 在 Linux 下你会使用 EOF 字符
  • 如果你想明确地读取一个,你应该试试std::getline()
  • 要么读取整行(通过std::getline())要么使用程序参数
  • 我的问题错了吗,如果不是,为什么我会投反对票?

标签: c++ algorithm while-loop c++14 user-input


【解决方案1】:

您需要通过文件结尾字符来终止您的输入(即在 Windows 上为 CTRL-Z,在 Mac/Unix 上为 CTRL-D),而不是只需通过行尾(即 Enter)。

简单的 Enter 被解释为空白,operator&gt;&gt; 在读入整数数据类型时会简单地忽略它。

CTRL-Z / End-Of-File 相反,使任何operator&gt;&gt; 失败并出现错误。

另见this SO answer

注意:输入f 也会终止你的循环,因为f 不是一个有效的整数;因此,std::cin &gt;&gt; valuevalue 的类型为 int 以及像 f 这样的输入也会失败。更准确地说:operator&gt;&gt; 实际上返回对输入流的引用,但如果读入一个值失败,则在流上设置failbit,然后在布尔表达式中解释流对象(隐式调用basic_istream::operator bool() ) 返回false;所以也许这本书的作者不想在书中的各个部分解释这些细节:-)

【讨论】:

  • 所以这不应该写在书里
  • 如果该部分是关于解释operator &gt;&gt; 及其行为,那么我想应该解释一下。如果该示例是关于演示其他内容,那么...
  • 最后一件事,是否可以编写一个在空格后停止的代码
  • 感谢您的耐心等待
【解决方案2】:

这是预期的吗?

是的,operator&gt;&gt; 默认忽略前导空格,包括换行符。

如果是,是否有任何代码在输入换行符后停止?

使用std::cin.getline()std::getline() 而不是operator&gt;&gt;。然后,您可以使用 operator&gt;&gt;std::istringstream 来解析每一行的值,例如:

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    std::string line;
    int sum, value;

    do
    {
        std::cout << "Enter a set of numbers, or a blank line to exit: ";
        if (!std::getline(std::cin, line) || line.empty())
            break;

        // read until end-of-line, calculating a running total of all values read
        std::istringstream iss(line);
        sum = 0;
        while (iss >> value)
            sum += value; // equivalent to sum = sum + value

        std::cout << "Sum is: " << sum << std::endl;
    }
    while (true);

    return 0;
}

Live Demo

【讨论】:

    【解决方案3】:

    这是预期的吗?

    是的while (std::cin &gt;&gt; value) 就是这样做的。有关更多解释,请参阅此答案:How is "std::cin>>value" evaluated in a while loop?

    是否有任何代码在输入换行符后停止?

    &gt;&gt; 只是忽略一个空格(@StephanLechner 也提到过)

    你可以做的是:

    1. 只要给出一个条件;如果它只满足break 循环。你 还可以提供一个控制台输出以使其更易于理解 用户。例如:

      std::cout << "Enter value to sum or press -1 to exit" << std::endl;
      
      while (std::cin >> value && value != -1) // if value == -1, loop stops.
      {
          sum += value;
      }
      
    2. 您可以简单地在字符末尾终止:

      • CTRL-Z 在 Windows 上
      • CTRL-D 在 Mac/Unix 上

    【讨论】:

    • 只有当输入为 -1 时才会中断这个循环
    • 不,您也可以在这里选择其他选项,使用 Stephan Lechner 提到的文件结尾字符。
    • 非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2015-02-04
    相关资源
    最近更新 更多