28

在下面的循环中,如果我们输入字符cin而不是预期的数字,那么它将进入无限循环。谁能向我解释为什么会发生这种情况?

当我们使用cin时,如果输入不是数字,那么有没有办法检测到以避免上述问题?

unsigned long ul_x1, ul_x2;

while (1)
{
  cin >> ul_x1 >> ul_x2;
  cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
4

4 回答 4

36

好吧,您总是会有一个无限循环,但我知道您真正想知道的是为什么 cin 不会在每次循环迭代时不断提示输入,从而导致您的无限循环自由运行。

原因是因为 cin 在您描述的情况下失败并且不会再读取这些变量的任何输入。通过给 cin 错误输入,cin 进入失败状态并停止提示命令行输入,从而导致循环自由运行。

对于简单的验证,您可以尝试使用 cin 通过检查 cin 是否处于失败状态来验证您的输入。当失败发生时清除失败状态并强制流丢弃错误的输入。这将使 cin 恢复正常操作,因此您可以提示更多输入。

  if (cin.fail())
  {
     cout << "ERROR -- You did not enter an integer";

     // get rid of failure state
     cin.clear(); 

     // From Eric's answer (thanks Eric)
     // discard 'bad' character(s) 
     cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

  }

对于更复杂的验证,您可能希望先读入一个字符串,然后对字符串进行更复杂的检查,以确保它符合您的预期。

于 2011-05-03T02:48:59.820 回答
11

注意力

请注意以下解决方案。清除您的案例中的错误尚未完成。你仍然会得到一个无限循环!

if (cin.fail())
{
     cout << "Please enter an integer";
     cin.clear();
}

完整的解决方案

原因是您需要清除流的失败状态,以及丢弃未处理的字符。否则,坏字符仍然存在,您仍然会出现无限循环。您可以简单地使用 std::cin.ignore() 来实现这一点。例如,

if (cin.fail())
{
         cout << "Please enter an integer";
         // clear error state
         cin.clear();
         // discard 'bad' character(s)
         cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

另一种解决方案

你也可以使用getlineandstringstream来实现。这是一个简短的例子。

   string input;
   while (1)
   {
      getline(cin, input);
      stringstream(input) >> x;
      cout << x << endl;
   }
于 2011-05-03T03:02:35.240 回答
2

或许,是因为,

  1. cin 是一个流功能。当输入非数字而不是数字时,将被忽略。并提示您重新输入。
  2. 即使您确实提供了数字输入,由于您处于无限循环中,因此系统会提示您输入更多输入。

你可以这样解决这个问题: 1. 创建一个函数来接收字符串输入。2. 转换后以数字形式返回。使用 strtod() 进行转换。

希望这可以帮助 :)

于 2011-05-03T03:08:46.670 回答
1

另一种选择是运营商!,相当于成员函数fail()

//from Doug's answer
if ( !cin )
{
   cout << "ERROR -- You did not enter an integer";

   // get rid of failure state
   cin.clear(); 

   // From Eric's answer (thanks Eric)
   // discard 'bad' character(s) 
   cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
于 2018-01-27T19:03:21.263 回答