Fgets-Как запретить пользователю превышать Maxsize? - PullRequest
1 голос
/ 01 июня 2019

Я использую fgets для получения имени от пользователя и помещаю его в массив символов. Если пользователь дает, скажем, за пределами maxsize в fgets, то моя программа имеет проблему. Я думал, что если пользователь превышает maxsize, возвращается NULL. Но это не так. Как я могу контролировать эту ошибку?

Конечно, я могу установить maxsize на 200 и даже больше. Но я думаю, что это не очень хорошее решение.

Я использовал fgets внутри оператора if, и если он ==NULL, я печатаю ошибку, но, как я уже сказал, это не будет работать, если пользователь превысит maxsize.

 fgets(name, 20, stdin);

Ответы [ 2 ]

2 голосов
/ 01 июня 2019

Что касается fgets, это не ошибка. Когда вы делаете fgets(name, 20, stdin), он будет просто читать до 19 символов из стандартного ввода (или меньше, если один из символов '\n'). Остальные символы останутся в стандартном вводе, и при следующем вызове функции ввода их заберут.

Вы можете обнаружить этот случай, проверив успешный вызов fgets, где строка не содержит '\n':

if (!fgets(name, 20, stdin)) {
    // fgets failed; handle error
}
if (!strchr(name, '\n')) {
    // no newline in 'name'; a partial line was read
}

Затем у вас есть выбор: выделять больший буфер, или отбрасывать оставшуюся часть строки, или жаловаться пользователю.

0 голосов
/ 01 июня 2019

Конечно, я могу установить максимальный размер на 200 и даже больше.Но я думаю, что это не очень хорошее решение.

Этот подход не так уж и плох.

Создание некоторого my_gets(), который позволяет огромные строк, дает неограниченную памятьуправление ресурсами для пользовательского ввода - потенциальный хакерский эксплойт.Огромная строка, скорее всего, ошибочный ввод или злонамеренный взлом кода.

Я бы выбрал @ Константин Георгиу и использовал бы большой, но вменяемый верхний предел.Затем определите такие большие строки как ошибочные / враждебные.

Обратите внимание, что строки текстового файла имеют ограничение среды .Таким образом, доказательство огромных буферов может быть спорным.

Реализация должна поддерживать текстовые файлы со строками, содержащими не менее 254 символов, включая завершающий символ новой строки.Значение макроса BUFSIZ должно быть не менее 256. C11 §7.21.2 7

#define MY_BUFSIZE ((BUFSIZE < 4096) ? BUFSIZE : 4096)

char name[MY_BUFSIZE + 2];
if (fgets(name, sizeof name, stdin)) {
  if (strlen(name) >= MY_BUFSIZE) Too_long_error(); 

Примечание: ввод необычно читается в виде нулевого символа рендеринга fgets() проблемного.

...