当我请求号码但用户输入非号码时,如何防止失控的输入循环?

时间:2011-02-01 17:02:48

标签: c++ cin

如果您输入错误的类型,我需要知道如何使我的cin语句看起来不会“删除”。代码在这里:

int mathOperator()
{
  using namespace std;

  int Input;
  do
  {
    cout << "Choose: ";
    el();
    cout << "1) Addition";
    el();
    cout << "2) Subtraction";
    el();
    cout << "3) Multiplication";
    el();
    cout << "4) Division";
    el();
    el();
    cin >> Input;

  }
  while (Input != 1 && Input != 2 && Input!=3 && Input!=4);
  return Input;
}

执行,输入,例如,一个字符,它循环不间断,就好像cin语句不存在一样。

6 个答案:

答案 0 :(得分:5)

您必须检查输入是否成功并在不输入时进行处理:

int mathOperator() {
  using namespace std;

  int Input;
  do {
    cout << "Choose: ";
    el();
    cout << "1) Addition";
    el();
    cout << "2) Subtraction";
    el();
    cout << "3) Multiplication";
    el();
    cout << "4) Division";
    el();
    el();
    while (!(cin >> Input)) {  // failed to extract
      if (cin.eof()) {  // testing eof() *after* failure detected
        throw std::runtime_error("unexpected EOF on stdin");
      }
      cin.clear();  // clear stream state
      cin.ignore(INT_MAX, '\n');  // ignore rest of line
      cout << "Input error.  Try again!\n";
    }
  } while (Input != 1 && Input != 2 && Input!=3 && Input!=4);
  return Input;
}

如果不检查提取是否成功,则cin处于失败状态(cin.fail())。一旦处于失败状态,稍后的提取将立即返回而不是尝试从流中读取,从而有效地使它们成为无操作 - 导致无限循环。

答案 1 :(得分:3)

除非您完全确定输入的格式正确,否则您很少直接从输入流中使用operator>>

通常使用std::getline读取一行更容易,将其放入std::istringstream,然后从那里读取。如果失败,则打印/记录错误消息,丢弃该行的其余部分,然后(可能)转到下一行。

答案 2 :(得分:2)

char Input;

 do
 {
// same code 
 }
 while (Input != '1' && Input != '2' && Input != '3' && Input!='4');
 return Input;

<强> [编辑]

如果你想将char转换为int,你可以使用这段代码

int i = (Input - 48);

答案 3 :(得分:2)

请勿阅读int,请阅读char,因此cin会传递任何无效字符

答案 4 :(得分:2)

读取错误值后,cin处于“失败”状态。你必须重置它。

您必须同时清除错误标志并清空缓冲区。因此:

   cin.clear(); 
   cin.ignore(std::numeric_limits<streamsize>::max(), '\n');

第二次调用“刷新”可能存在的任何数据的输入缓冲区,以便为下一次“cin”调用做好准备。

如果你发现自己在代码中“编写了这两行”,你可以编写一个简单的内联函数来替换它。

   inline void reset( std::istream & is )
   {
       is.clear();
       is.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
   }

虽然我已经使这个函数占用了任何istream,但大部分时间它只用于用户输入的cin并输入无效的东西。如果它是无效的文件或字符串流输入,则无法修复它,您最好只抛出异常。

答案 5 :(得分:0)

我同意char很方便,因为你总是可以转换为int,回答你为什么会发生这种情况的问题,当cin输入作为int执行但是输入了char时,输入是在循环期间保持在输入流中,这就是它似乎“消失”的原因。

有关详细信息,请参阅http://www.daniweb.com/forums/thread11505.html

中Narue的帖子