scanf не должен превышать переполнение буфера
Вопрос
У меня есть буфер, и я не хочу, чтобы пользователь вводил больше символов, чем может вместить буфер (во избежание переполнения буфера).
Я использую scanf
и сделали вот так:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
Однако я знаю, что я защищен, если пользователь вводит более 30.Однако, если пользователь вводит более 30, будет ли буфер завершаться нулем?
Решение
scanf()
со спецификатором преобразования «%s» добавляет в буфер завершающий нулевой символ.
Но, вы запрашиваете 30 символов, что на самом деле означает 31, а места хватает только на 30.Вы должны использовать максимальную ширину поля 29.
char buffer[30] = {'\0'};
scanf("%29s", buffer);
Также обратите внимание, что спецификатор преобразования "%c"
работает почти так же, как "%s"
, но не добавляет завершающий нулевой символ и не удаляет пробел из ввода.В зависимости от того, чего вы ожидаете, это может быть лучше, чем использование «%s».
char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
Другие советы
Из scanf
руководство:
с Соответствует последовательности небелых символов;Следующим указателем должен быть указатель на ChAR, и массив должен быть достаточно большим, чтобы принять всю последовательность и прекращающий символ NUL.Входная строка останавливается в промежуточном пространстве или по максимальной ширине поля, в зависимости от того, что это произойдет.
Вы вызываете UB.Пытаться:
#define str(x) #x
#define xstr(s) str(x)
#define BUFSIZE 30
char buffer[ BUFSIZE + 1 ];
scanf("%" xstr(BUFSIZE) "s", buf);
Игнорировать что-либо за пределами BUFSIZE
символы подавляют присвоение:
scanf("%" xstr(BUFSIZE) "s%*", buf);
Вы также должны проверить, ввел ли пользователь возврат/новую строку и завершить работу. scanf
если у него есть:
scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
и хорошей практикой является проверка возвращаемых значений, поэтому:
int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
и, наконец, проверьте, осталось ли что-нибудь (например, перевод строки, и используйте его):
if (!feof(stdin))
getchar();
У вас произойдет переполнение буфера, поскольку вы не допустили завершающий символ NUL.Объявите свой буфер следующим образом:
char buffer[31];
и с тобой все будет в порядке.