提问者:小点点

输入字符串而需要数字时使用cin的无限循环


在下面的循环中,如果我们键入字符作为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;
}

共3个答案

匿名用户

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

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

对于简单的验证,您可以尝试使用cin,通过检查cin是否处于失败状态来验证您的输入。 当发生fail时,清除fail状态并强制流丢弃错误输入。 这将使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');

  }

对于更复杂的验证,您可能希望首先读入字符串,然后对字符串进行更复杂的检查,以确保它与您所期望的匹配。

匿名用户

注意

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

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');
}

另一种解决方案

您还可以使用getLinestringstream来实现。 这里有一个简短的例子。

   string input;
   while (1)
   {
      getline(cin, input);
      stringstream(input) >> x;
      cout << x << endl;
   }

匿名用户

也许是因为,

  1. CIN是一个流函数。 当输入非数字而不是数字时,将忽略它。 并提示您重新输入。
  2. 即使您给出了数字输入,也会提示您输入更多,因为您处于无限循环中。

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

希望这能有所帮助:)