当将文件重定向到标准输入时,getline会导致无限循环

时间:2012-10-14 02:49:19

标签: c++ infinite-loop getline

以下代码简单地回显了标准输出的标准输入。如果我像./a.out这样运行程序,我可以输入任何内容,程序运行正常。但是,如果我像./a.out < input.txt那样运行它,无论input.txt的内容是什么,我都会得到一个无限循环。

#include <iostream>

using namespace std;

int main() {
  string input;
  while (true) {
    cout << "Type your input: ";
    getline(cin, input);
    cout << input << endl;
  }
  return 0;
}

我做错了什么?

编辑:为了澄清,我希望在输入文件的输入完成后,getline等待来自stdin的更多输入。相反,当没有任何东西时,它会继续阅读。

3 个答案:

答案 0 :(得分:1)

你的循环没有终止条件,不管是休息,还是在while部分内。相反,你可能想要这个:

while (getline(cin, input))

当输入失败时,这将结束,很可能是因为已达到EOF。

答案 1 :(得分:1)

你的循环没有终止条件:while (true)在任何情况下都是无限循环 - 也就是说,没有中断/退出/等。在循环体中。

我猜测在使用你的程序回显stdin时,你可以按Ctrl-C结束它。使用./a.out运行程序,然后键入Ctrl-D(EOF):您还将获得无限循环。

查看getline的{​​{3}}:使用返回值结束循环:

while (getline(cin, input))

答案 2 :(得分:0)

你错误的是你忽略输入操作的结果,在这种情况下是getline

您绝不能忽略输入操作的结果。这样做总是一个编程错误。您无法知道或假设外部数据的状态,因此您必须始终检查输入操作是否成功。如果没有,则访问所声称的输入变量以进行读取通常是错误的,因此您确实需要每次都检查,并且访问结果之前。

在本例中,std::getline返回对流对象的引用,您可以将流评估为布尔值。当且仅当提取成功时,它评估为true;否则,你必须使用结果(并且可能会停止阅读)。

总而言之,代码应该是这样的:

for (std::string line; std::getline(std::cin, line); )
{
    // use "line"
}