Топ питань
Часова шкала
Чат
Перспективи
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