Лучшие вопросы
Таймлайн
Чат
Перспективы
Gets
Из Википедии, свободной энциклопедии
Remove ads
gets — функция, входящая в Стандартную библиотеку языка Си, объявляемая в заголовочном файле stdio.h, которая считывает строку стандартного ввода и помещает её в буфер, созданный вызывающей функцией. Если выдаёт ошибку, то теперь для её вызова следует использовать gets_s.
Реализация
Суммиров вкратце
Перспектива
Может быть реализована следующим способом (при помощи getchar):
char *gets(char *s)
{
/*очистка буфера ввода */
fflush(stdin);
int i, k = getchar();
/* Возвращаем NULL если ничего не введено */
if (k == EOF)
return NULL;
/* Считываем и копируем в буфер символы пока не достигнем конца строки или файла */
for (i = 0; k != EOF && k != '\n'; ++i) {
s[i] = k;
k = getchar();
/* При обнаружении ошибки результирующий буфер непригоден */
if (k == EOF && !feof(stdin))
return NULL;
}
/* Нуль-терминируем и возвращаем буфер в случае успеха.
Символ перевода строки в буфере не хранится. */
s[i] = '\0';
return s;
}
Программист должен знать максимум числа символов, которые должны быть считаны gets, чтобы удостовериться, что выделяется буфер достаточного размера. Подобное невозможно без информации о данных. Эта проблема может приводить к созданию ошибок и открывает простор для нарушений компьютерной безопасности при помощи переполнения буфера. Многие источники советуют программистам никогда не использовать gets в новых программах[1][2][3].
Применение gets весьма осуждается. Функция оставлена в стандартах C89 и C99 для обратной совместимости. Множество инструментов разработки ПО, как, например, GNU ld, выдаёт предупреждения в случае обнаружения при компоновке кода с использованием gets.
Remove ads
Альтернативы
Вместо gets могут быть использованы другие функции строкового ввода, что позволит избежать ошибок, связанных с переполнением буфера. Простейшим вариантом будет fgets. При замене кода вида
char buffer[BUFFERSIZE];
gets(buffer);
кодом вида
char buffer[BUFFERSIZE];
fgets(buffer, sizeof(buffer), stdin);
нужно иметь в виду, что вызов fgets(buffer, sizeof buffer, stdin) отличается от gets(buffer) не только защитой от переполнения буфера, но и тем, что fgets(buffer, sizeof buffer, stdin) сохраняет завершающий символ перевода строки (если ввод линии заканчивается символом перевода строки), в то время как gets(buffer) отбрасывает его.
Remove ads
Безопасность использования
Безопасное использование gets требует от программиста проверки того, что переполнение буфера не станет проблемой. Стандарт языка Си этого не гарантирует; тем не менее, существует несколько относительно усложненных способов проверки этого с различной степенью переносимости. Одним из возможных вариантов является защитная страница для защиты памяти. В сочетании с обработчиками исключений, такими как SIGSEGV и sigaction, защитная страница может помочь с обработкой ошибок.
Примечания
Ссылки
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads