В этом случае происходит сбой вашей программы, поскольку scanf()
имеет небезопасный интерфейс для строк .Он не может знать, что ваш параметр ch
является массивом, достаточно большим, чтобы содержать строку из 9 символов плюс завершающий ноль.В результате, он очень рад, что читает символы из stdin
и сохраняет их в памяти далеко за концом массива.
Если ваша программа падает, вам действительно повезло.В худшем случае злоумышленник использовал тщательно созданную строку, чтобы манипулировать содержимым стека таким образом, чтобы он получил контроль над вашим компьютером.Это пример атаки переполнения буфера.Это звучит маловероятно, но было задокументировано, что это происходит в большом количестве случаев.
Используется только для чисел, scanf
, как правило, достаточно безопасно, но не очень хорошо обрабатывает ошибки во входных данных.В результате, обычно хорошей идеей будет использовать что-то вроде fgets()
для чтения ввода (он имеет параметр длины буфера для управления переполнением) и sscanf()
для анализа этого буфера, проверяя его возвращаемые значения на разумность, пока выидти.
Редактировать: Как отмечается в комментарии от R , я переоценил опасности, присущие интерфейсу scanf
.При правильном использовании спецификатора ширины поля во всех строках scanf
становится безопаснее.Но тогда вы берете на себя ответственность за гарантию того, что указанная ширина вписывается в буфер.Например, вы должны написать scanf("%9s",ch);
, потому что ваш буфер был объявлен длиной в десять байтов, и вам нужно место для завершающего nul.
Обратите внимание, что вы также должны проверять возвращаемое значение из scanf()
.Он возвращает количество полей, которые он успешно сопоставил, или EOF
, если произошла ошибка ввода-вывода.Например, он может вернуть 0, если пользователь ввел «abc», когда ожидал число.