Как работать с wscanf в бесконечном цикле?

Имеется следующий код:

for (;;){
   // запрос от пользователя
   wscanf(L"%d", &user_request);
   if (user_request == 5){
      return 0;
   }
   wprintf(L"ok");
}

Переменная user_request имеет тип int. Если вводить только числа, то программа работает, как и ожидается: выводит один раз сообщение и ждет следующего ввода или выходит, если было введено число 5. Однако если попробовать передать символ, то программа будет бесконечно выводить ok. Почему так происходит и как можно этого избежать?


Ответы (1 шт):

Автор решения: KoVadim

wscanf возвращает кол-во прочитанных переменных. В Вашем случае оно может возвратить 1, если прочиталось, и 0 - если не удалось прочитать, EOF - если поток закрыт. Дальше один if и готово

for (;;){
   // запрос от пользователя
   int c = wscanf(L"%d", &user_request);
   if (c != 1) { /*ups*/ return 1; }
   if (user_request == 5){
      return 0;
   }
   wprintf(L"ok");
}

Если нужна "хитрая логика", а пользователь может вводить все, что он хочет, тогда где то так

int main()
{
  int user_request = 0;
  for (;;){
     // запрос от пользователя
     wchar_t s[1000]; // 1000 символов хватит всем :)
     fgetws (s , 1000 ,stdin);
     int c = swscanf(s, L"%d", &user_request);
     if (c != 1) { printf("bad input, please enter again\n"); continue; }
     if (user_request == 5){
        return 0;
     }
     wprintf(L"ok");
  }

}

то есть, спрашиваем у пользователя строку, а потом пробуем ее распарсить по нужному шаблону. Хотя если Вам нужно именно пять, может лучше прям как строки сравнить?

→ Ссылка