Подтвердить что ты не робот

Бесконечная петля с 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;
}
4b9b3361

Ответ 1

Ну, у вас всегда будет бесконечный цикл, но я знаю, что вы действительно хотите знать, потому что cin не продолжает запрашивать ввод на каждой итерации цикла, заставляя ваш бесконечный цикл использовать freerun.

Причина в том, что cin не работает в описанной вами ситуации и больше не будет считывать эти переменные. Предоставляя отрицательный вход cin, cin получает в состоянии fail) и перестает запрашивать командную строку для ввода, что приводит к свободному запуску цикла.

Для простой проверки вы можете попытаться использовать cin для проверки своих входов путем проверки того, находится ли cin в состоянии сбоя. Когда сбой происходит очистить состояние отказа и заставить поток выбросить плохой ввод. Это возвращает cin для нормальной работы, поэтому вы можете запросить больше ввода.

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

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

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

  }

Для более сложной проверки вы можете сначала прочитать строку и выполнить более сложные проверки строки, чтобы убедиться, что она соответствует ожидаемому.

Ответ 2

Внимание

Обратите внимание на следующее решение. Он еще не завершен, чтобы устранить ошибку в вашем случае. Вы все равно получите бесконечный цикл!

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

Другое решение

Вы также можете использовать getline и stringstream для достижения. Вот краткий пример.

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

Ответ 3

Возможно, это потому, что

  • cin - это потоковая функция. Когда вместо цифр вводится вместо чисел, он игнорируется. И вы запрос на повторный вход.
  • Даже если вы указали числовые входы, вам будет предложено ввести больше входов, поскольку вы находитесь в бесконечном цикле.

Вы можете решить эту проблему следующим образом: 1. Создайте функцию для ввода строкового ввода. 2. верните его как числовое после преобразования. Используйте strtod() для преобразования.

Надеюсь, что это поможет:)

Ответ 4

Другой альтернативой является operator!, это эквивалентно функции-члене не работают()

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

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

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