обработка ошибок scanf C - PullRequest
2 голосов
/ 11 мая 2011

Скажи, если я хочу, чтобы вход был

[Name] [Name]

Как бы я обнаружил

[Name] [Name] [Name] 

и вернул ошибку?

Вот что у меня так далеко

1010 *

Ответы [ 2 ]

4 голосов
/ 11 мая 2011

Это домашняя работа, поэтому вам может потребоваться работать с определенными (произвольными) ограничениями.Тем не менее, фраза «scanf обработка ошибок» является чем-то оксюморонным в языке программирования C.

лучший способ сделать это - прочитать строку / другой подходящий фрагменти разобрать его с помощью строковых функций Си.Вы можете сделать это в одной строке scanf, но есть много недостатков:

  1. Вы можете защититься от переполнения буфера, но если буфер недостаточно велик, вы не сможете восстановить.
  2. Вы можете указать определенные диапазоны символов для своих строк, но это начинает выглядеть немного регулярным, и поведение формата "%[" scanf не является обязательным в стандарте.
  3. Вы можете проверить третье имя, но код выглядит не интуитивно понятным - не похоже, что вы хотите только два имени, похоже, что вы хотите три.scanf также дает вам очень мало контроля над тем, как вы обрабатываете пробелы.

РЕДАКТИРОВАТЬ: я изначально думал из вашего вопроса, что имена были заключены в квадратные скобки (а-ля "[Bruce] [Wayne]"), но теперь он появляетсяэто было просто ваше соглашение для обозначения заполнителя.

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

Если вам нужно использовать scanf, ваш формат в основном таков:

" %s %s %s"

С третьим нежелательным.Как показывает ответ @ Constantinius , вам нужно прочитать данные в три буфера и проверить, прошел ли третий.Однако, если вы читаете несколько последовательных строк этих данных, то первая запись следующей строки будет удовлетворять третий слот, ложно давая вам ошибку.Я настоятельно рекомендую использовать fgets и sscanf или отключить sscanf для более точного ручного анализа в этом случае.

Вот ссылка на справочную страницу fgets , если выпропустил тот, который я пробрался ранее.Если вы решите отказаться от sscanf, обратите внимание на некоторые другие функции: strchr (или strspn или strcspn)чтобы узнать, как долго это имя, strcpy или memcpy (но, пожалуйста, не strncpy, это не то, что вы думаете) скопировать данные в буферы.

3 голосов
/ 11 мая 2011

scanf возвращает количество правильно преобразованных аргументов.Таким образом, в вашем первом случае возвращаемое значение будет 2, в последнем случае 3.

Чтобы проверить правильное количество параметров, это может помочь:

char in[20];
char out[20];
char error[20];
int check;

check = scanf(" %s %s %s", out, in, error);
if(check != 2)
{
    // TODO: error handling
}

РЕДАКТИРОВАТЬ: теперь этодолжно работать, см. комментарии ниже.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...