Как проверить ввод с помощью scanf

Как я могу проверить ввод пользователя с помощью scanf. Прямо сейчас у меня есть что-то вроде этого, но не работает.

ПРИМЕЧАНИЕ. У меня есть atoi, чтобы проверить, работает ли проверка scanf.

scanf("%[0987654321.-]s",buf); i = atoi(buf); if(i) index = i; 

Использование scanf() как правило, является плохой идеей для ввода пользователем, так как отказ оставляет указатель FILE в неизвестном месте. Это связано с тем, что scanf означает «отсканированный формат» и немного больше неформатирован, чем ввод пользователя.

Я бы предложил использовать fgets() чтобы получить строку, а затем sscanf() в строке, чтобы проверить и обработать ее.

Это также позволяет вам проверять строку для тех символов, которые вы хотите (либо через цикл, либо с помощью регулярного выражения), что не подходит для семейства функций scanf .

В качестве примера использование scanf() с "%d" или "%f" остановится на первом "127hello" , "127hello" номера, поэтому не будет ловить завершающие ошибки, такие как "127hello" , которые просто дадут вам 127. И используя он с неограниченным %s просто попросит переполнение буфера.

Если вы действительно должны использовать спецификатор формата []scanf или sscanf ), я не думаю, что за ним следует s .

И для надежного входного решения, использующего этот совет, см. Здесь . Когда у вас есть строка ввода в виде строки, вы можете использовать ее в своем сердце.

Кажется, вы хотите проверить строку как входную. Это зависит от того, хотите ли вы проверить, что ваша строка содержит double или int. Следующие проверки для двойного (допустимое и конечное пробелы разрешено).

 bool is_double(char const* s) { int n; double d; return sscanf(s, "%lf %n", &d, &n) == 1 && !s[n]; } 

sscanf вернет преобразованные элементы (без «% n»). n будет задано количество обработанных входных символов. Если весь вход был обработан, s [n] вернет завершающий символ 0. Пространство между двумя спецификаторами формата учитывает необязательные конечные пробелы.

Следующие проверки для int, используемые методы:

 bool is_int(char const* s) { int n; int i; return sscanf(s, "%d %n", &i, &n) == 1 && !s[n]; } 

Здесь был вопрос, который включает в себя также больше возможностей для этого, как использование streamов строк и функций от boost, таких как lexical_cast и т. Д. Обычно они должны быть предпочтительнее таких функций, как scanf, так как очень легко забыть передать некоторые «%» в scanf или какой-то адрес. scanf не распознает это, но вместо этого будет делать произвольные вещи, в то время как lexical_cast, например, выдает исключение, если что-то не так.

Мой подход strtol() бы в том, чтобы прочитать ввод пользователя в строку и затем преобразовать его в long с помощью strtol() . strtol() возвращает указатель на первый символ в строке ввода, который он не смог обработать, поэтому, проверив этот символ, вы должны знать, была ли проанализирована полная строка, например:

 char *string; char *endptr; long result; scanf("%as", string); errno = 0; result = strtol(string, &endptr, 10); if (ERANGE == errno) printf("Input number doesn't fit into long\n"); else if (*endptr) printf("%s is not a valid long number - it contains invalid char %c\n", string, *endptr); else printf("Got %ld\n", result); 

В этом fragmentе scanf() указывается, что автоматически выделяет string достаточно большую, используя модификатор формата «a» (это расширение GNU). Если вы не используете GNU, выделите string вручную и ограничьте максимальный размер в формате scanf() .

Такой подход позволяет улучшить обработку ошибок.

То, что вы указали в первом аргументе scanf – это спецификаторы преобразования . scanf попытается преобразовать вход в формат, но иногда вы можете быть удивлены тем, с чем он будет соответствовать 🙂

Первая проверка, которую вы должны сделать, – это вернуть значение из scanf (это даст вам количество совпадающих входов). Если вы не получите номер, который вы ожидаете, тогда вы знаете, что что-то не так с вводом. В вашем случае это должно быть 1.

 if( scanf("%[0987654321.-]s", buf) == 1 ) { if( sanit_check( buf ) ) { /* good input */ } else { /* invalid input */ } } else { /* invalid input */ } 

Кроме того, вам нужно будет сделать ваши проверки на работоспособность при конверсии, которую вы попросили scanf .

Если вы пытаетесь прочитать только номер, используйте:

 int i; scanf( "%d", &i ); 

Если вам нужно выполнить более сложную проверку, вам придется сделать это самостоятельно. Scanf не сделает это за вас.

«buf» должен быть указателем. Похоже, вы проходите по значению.

  • Чтение строки из ввода с символом пробела?
  • Программа не выполняет gets () после scanf (), даже используя fflush (stdin)
  • что такое эквивалент Java sscanf для синтаксического анализа значений из строки с использованием известного шаблона?
  • C - попытка чтения одного символа из stdin (и сбоя) w / scanf / getchar
  • Как я могу прочитать строку ввода неизвестной длины?
  • Почему scanf () нуждается в & operator (address-of) в некоторых случаях, а не в других?
  • Как сканировать строки с пробелами в них с помощью scanf ()?
  • Scanf не будет выполняться во второй раз
  • printf не печатать на консоли
  • В чем разница между sscanf или atoi, чтобы преобразовать строку в целое число?
  • читать разделенный запятыми вход с scanf
  • Давайте будем гением компьютера.