这个循环如何打印一系列作为输入输入的整数?

问题描述

让我们输入:10 20 30 40 50
我希望输出与输入完全一样,但以下代码仅打印 10 作为输出

#include<iostream>
int main() {

    std::cout << " Please enter sequence of numbers separated by space"
              << " then press enter : ";

    int numbers;
    std::cin>>numbers;
    std::cout << numbers <<' ';
}

我认为的原因是输入运算符“>>”将 10 作为输入并在输入流中留下空间。对于下一个输入,cin 找到空格并得出输入已结束的结论。因此,输出为 10。

现在,如果我使用 while 循环输入,代码会准确打印出我想要的内容

 int numbers;
 while(std::cin >> numbers)

 std::cout << numbers <<' '; 

输出10 20 30 40 50

为什么使用 while 循环输入可以正常工作?请解释到底发生了什么。

解决方法

您对第一个示例中发生的事情非常正确。您在 10 20 30 40 中输入 stdin,但它只将第一个数字 10 作为输入并将其存储到 numbers 中。其余部分停留在 stdin 中,程序退出。

通过适当的缩进,我相信您在第二个示例中的代码会清晰得多。

#include <iostream>

int main()
{
    int n = 0;
    while (std::cin >> n)
        std::cout << n << ' ';
}

基本上,这个程序以一种非常奇怪的方式工作。在 while 循环的第一次运行中,假设您输入了 1 2 3。对其进行可视化,stdin 将如下所示:

1 2 3

现在,它必须从中获取一个数字。所以它需要 1 然后找到一个空格,所以它停止了。现在 1n 中,它打印 1 后跟一个空格。在循环的第一次运行之后,stdin 看起来像这样:

2 3

在循环的第二次运行中,它实际上并没有提示您进行更多输入,因为 stdin 不为空。所以它只会从已经存在的东西中获取输入。它在开头看到 2,取下它并在下一个空格处停止,并将其放入 n。然后打印 n,后跟一个空格。 stdin 现在看起来像这样:

3

同样的事情发生在 3。取3放入n打印出来,这次stdin已经清零了。此后,std::cin 不再接受输入并在循环的最后一次检查中返回 false,因为它已命中 eof。因此,希望让事情更清楚一些,展开循环后,您的程序如下所示:

#include <iostream>

int main()
{
    int n = 0;
    std::cin >> n;         // Here you input "1 2 3",1 is taken leaving "2 3" in stdin
    std::cout << n << ' '; // "1 " printed
    std::cin >> n;         // 2 is taken from stdin,leaving "3"
    std::cout << n << ' '; // "2 " printed
    std::cin >> n;         // 3 is taken from stdin,nothing left
    std::cout << n << ' '; // "3 " printed
}
,

实际上当您输入 10 20 30 40 50 时。它只得到 10,因为它忽略了空格后的所有值。 如果您获得所有值,请尝试 Array 并在进一步计算中使用这些值,并使用 for 和 while 循环打印这些值。

,

你可以用这个函数循环你想输入的每个数字:

std::string spaceAfterDigit(int len)
{
    std::string digits[256];
    std::string result;
    std::cout << "Type digits but after every digit press enter: ";
    for (int i = 0; i < len; i++)
    {
        std::cin >> digits[i];
        std::cout << " ";
        result += digits[i] + " ";
    }

    return result;
}

如果你想将字符串转换为 int 只需使用 stringstream:

stringstream ss;  
ss << result;  
ss >> resultInt;
,

在下文中,我将展示第二个发布片段的源代码产生的输出 C++ Insights(参见例如 here,缩进我的):

#include<iostream>

int main()
{
  std::operator<<(
    std::operator<<(
      std::cout," Please enter sequence of numbers separated by space"
    )," then press enter : "
  );

  int numbers;
  while ( static_cast<bool>(
            static_cast<const std::basic_ios<char>&>(
              std::cin.operator>>(numbers)
            ).operator bool()
          ) )
  {
    std::operator<<(std::cout.operator<<(numbers),' ');
  }
  
}

似乎发生了很多事情,所以让我们了解一下要点。

  • 尽管有不幸的缩进选择,但 OP 的代码段等效于:

    int numbers;
    while ( std::cin >> numbers )
    {
        std::cout << numbers <<' '; 
    }
    

    这是一个简单的 while 循环,其中在每次迭代时评估的条件是 std::cin >> number(稍后会详细介绍)并且只要条件评估 {{1} },是true。因此,这是一个循环,它重复地从输入流中提取一个(单个)数字并将其放入输出流(连同一个空格字符)。

  • 现在让我们仔细看看这种情况。

    std::cout << numbers << ' '; 实际上是对 std::cin >> number 的成员函数 operator>>(int &) 的调用,它

    提取可能跳过前面空格的整数值。该值存储为给定的参考值。 [...]
    返回值:std::cin

    因此它不仅从输入流中提取值,而且还返回对 *this 的引用。这很有用,因为我们可以使用返回值来连接对这个对象的操作。

  • std::cin 的另一个重要成员函数是 operator bool,它

    检查流是否没有错误。 [...]
    如果流没有错误并且准备好进行 I/O 操作,则返回 std::cin。具体来说,返回 true
    此运算符可以使用返回流引用作为循环条件的流和函数,从而产生惯用的 C++ 输入循环,例如 !fail()while(stream >> value) {...}。只有当输入操作成功时,这样的循环才会执行循环体。