在C ++中忽略std :: cin上的EOF

时间:2009-03-23 17:32:44

标签: c++ console stdin

我有一个实现交互式shell的应用程序,类似于Python控制台/ irb的工作方式。现在的问题是,如果用户意外点击^D发出EOF并且我的getline()调用返回一个空字符串,我将其视为“无输入”并再次显示提示。

然后导致无限循环打印提示。

现在在Python中我会通过捕获EOFError来解决这个问题,但是在C ++中没有引发任何异常我可以捕获并且cin上似乎没有设置忽略EOF。 / p>

任何提示?

5 个答案:

答案 0 :(得分:7)

如果它无法读取任何内容,则会设置failbit。只需在if条件下测试流,然后清除该位:

if(!getline(std::cin, myline)) {
    std::cin.clear();
    std::cout << "you should enter something" << std::endl;
}

在内部,序列就是这样:

  • 在终端上等待一个字符串。终端将阻止,直到用户发出换行符。可能出现两个可能的错误情况
    1. 用户立即按下EOF。这将使getline完全不读取任何内容,并设置failbiteofbit
    2. 用户输入内容然后按EOF。这将使getline消耗某些东西,然后在尝试获取下一个字符时它会击中EOF。这会导致eofbit设置。
  • 你会尝试再读一些东西。提取函数将创建一个istream::sentry类型的对象,该对象检查流的状态。如果设置了任何错误位,将导致提取功能立即返回。这导致了无休止的循环。

拨打clear()会清除所有错误位,您可以继续阅读您的内容。

答案 1 :(得分:3)

感谢litb提供正确的解决方案:

if (!getline(std::cin, str)) {
    std::cin.clear();
    std::cout << std::endl;
}

答案 2 :(得分:1)

getline()函数使用以下位表示错误:

  • eofbit
  • failbit
  • badbit

在继续操作之前,请尝试检查这些内容。

答案 3 :(得分:0)

请参阅http://www.horstmann.com/cpp/pitfalls.html

您可以使用以下代码:

while (cin)
{  int x;
   cin >> x;
   if (cin) a.push_back(x);
}

答案 4 :(得分:0)

好的,在其他答案中使用cin.clear()被描述为一种可能的解决方案。

另一个技巧是通过将终端设置为另一种模式,您可以使用其他方法处理来自控制台的输入,而不是典型的标准,这样您就可以直接处理Ctrl + D.在RAW模式或其他模式下,您可以更加直接地访问用户端的输入和控制序列(如Ctrl + D或Ctrl + C),不再处理它们。

有些图书馆可能会尝试收集更多信息(甚至节省编码时间):

½您可以在文档here中找到有关您的问题的一些信息。