scanf не должен превышать переполнение буфера

StackOverflow https://stackoverflow.com/questions/1721073

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть буфер, и я не хочу, чтобы пользователь вводил больше символов, чем может вместить буфер (во избежание переполнения буфера).

Я использую 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];

и с тобой все будет в порядке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top