带限制的cin.ignore是否继续丢弃新输入?

时间:2015-09-22 23:24:27

标签: c++ stdin

我正在尝试学习C ++,并且已经陷入了一些我无法理解的NO行为的rabbithole。这是我的代码:

cin

这里的问题是,当我第一次输入无效输入(例如某些字母字符)时,程序会卡在#include <iostream> using namespace std; int main() { int num; // Get valid input do { if (!cin) { // Clear error state and flush any garbage input cin.clear(); cin.ignore(numeric_limits<streamsize>::max()); } cout << "Please enter a number: "; cin >> num; } while (!cin); // Echo back what we heard cout << "You entered: " << num << "\n"; cin.get(); } 语句上。我可以继续输入内容(包括换行符),程序永远不会超过该声明。

根据我的理解,这表明如果cin.ignore(numeric_limits<streamsize>::max())的第一个参数超过缓冲区的当前大小,则任何未来的字符(直到提供的限制)将继续被丢弃。它是否正确?如果正确,我该如何清除输入缓冲区而不影响将来的输入?

注意:出于某种原因,使用cin.ignore并在cin.ignore(numeric_limits<streamsize>::max(), '\n')之后添加cin.ignore()会使代码正常运行。这只是为了澄清我知道这种可能性存在,但我仍然有兴趣了解上面代码中出现的问题(cin >> num分隔符未指定)。

1 个答案:

答案 0 :(得分:1)

您的代码正在清除任何错误标记,然后丢弃其他字符,直到numeric_limits<streamsize>::max()EOF字符的硬限制(您通常可以使用 Ctrl + Z 输入一个字符) )被击中了。因此,正如您所怀疑的那样,它会不断丢弃您的输入。

您的代码的固定版本只能丢弃字符,直到找到换行符

#include <iostream>
#include <limits>

using namespace std;

int main()
{
  int num;

  // Get valid input
  do
  { 
    if (cin.fail())
    {
      // Clear error state and flush any garbage input
      cin.clear();
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    cout << "Please enter a number: ";
    cin >> num;

  } while (cin.fail());

  // Echo back what we heard
  cout << "You entered: " << num << "\n";

  cin.get();
}

Live Example

可能是更惯用和更紧凑的版本

#include <iostream>
#include <limits>
using namespace std;

int main()
{
  int num;

  // Get valid input
  while( (cout << "Please enter a number: ") && !(cin >> num) )
  {
    cout << "Invalid number entered" << endl;
    // Clear error state and flush any garbage input
    cin.clear();
    cin.ignore(cin.rdbuf()->in_avail());
  }

  // Echo back what we heard
  cout << "You entered: " << num << "\n";

  cin.get();
}

Live Example

正如您所指出的那样cin.rdbuf()->in_avail()可能是一个更简单的解决方案,因为它会完全丢弃流中可读取的字符数。