C++ 在需要输入数字的情况下输入字符串时,使用 cin 进行无限循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5864540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:03:49  来源:igfitidea点击:

Infinite loop with cin when typing string while a number is expected

c++validationinfinite-loopcin

提问by chanwcom

In the following loop, if we type characters as the cininput instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?

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

When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?

当我们使用 时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;
}

回答by Doug T.

Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.

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

The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail stateand stops prompting the command line for input causing the loop to free run.

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

For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the failstate and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.

对于简单的验证,您可以尝试使用 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');

  }

For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.

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

回答by Eric Z

Attention

注意力

Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!

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

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

Complete Solution

完整的解决方案

The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops. You can simply can std::cin.ignore() to achieve this. For example,

原因是你需要清除流的失败状态,以及丢弃未处理的字符。否则,坏字符仍然存在,你仍然会得到无限循环。您可以简单地使用 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');
}

Another Solution

另一种解决方案

You can also use getlineand stringstreamto achieve. Here is a brief example.

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

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

回答by itsols

Perhaps, it's because,

或许,是因为,

  1. cin is a streaming function. When a non-numeric is entered instead of numbers, it is ignored. And you are prompted for re-entry.
  2. Even if you did give numeric inputs, you will be prompted for more inputs since you're on an infinite loop.
  1. cin 是一个流函数。当输入非数字而不是数字时,它会被忽略。并提示您重新输入。
  2. 即使您确实提供了数字输入,由于您处于无限循环中,系统也会提示您进行更多输入。

You can solve this problem like this: 1. Create a function to take in a string input. 2. return it as numeric after conversion. Use strtod() for conversion.

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

Hope this helps :)

希望这可以帮助 :)

回答by Hani Shams

Another alternative is operator!,it is equivalent to member function fail()

另一种选择是运营商!,相当于成员函数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');
}