2

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

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

现在在 Python 中,我会通过 catch 来解决这个问题EOFError,但在 C++ 中,我可以捕捉到没有异常,而且似乎没有设置cin忽略 EOF。

有什么提示吗?

4

5 回答 5

7

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

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

在内部,您的情况是这样的:

  • 在终端上等待字符串。终端将阻塞,直到用户发出换行符。两种可能的错误情况
    1. 用户立即按下 EOF。这将使getlineread 什么都没有,它会设置failbiteofbit
    2. 用户输入一些东西,然后按 EOF。这将getline消耗一些东西,然后在尝试获取下一个字符时遇到 EOF。设置这个原因eofbit
  • 您将尝试再次阅读一些内容。提取函数将创建一个类型的对象,istream::sentry用于检查流的状态。如果设置了任何错误位,它将导致提取函数立即返回。这导致了之前的无限循环。

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

于 2009-03-23T17:37:27.680 回答
3

感谢 litb 的正确解决方案:

if (!getline(std::cin, str)) {
    std::cin.clear();
    std::cout << std::endl;
}
于 2009-03-23T17:51:19.300 回答
1

getline()函数使用以下位发出错误信号:

  • eofbit
  • 故障位
  • 坏比特

在继续之前尝试检查这些。

于 2009-03-23T17:35:51.083 回答
0

http://www.horstmann.com/cpp/pitfalls.html

您可以使用如下代码:

while (cin)
{  int x;
   cin >> x;
   if (cin) a.push_back(x);
}
于 2009-03-23T17:40:41.137 回答
0

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

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

您可能会尝试收集更多信息(甚至节省编码时间)的一些库:

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

于 2009-03-23T17:41:00.277 回答