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
у нових програмах.
Застосування gets
вельми засуджується. Функцію залишено в стандартах C89 і C99 задля зворотної сумісності. Безліч інструментів розробки ПЗ, як, наприклад, GNU ld, видає попередження в разі виявлення при компонуванні коду з використанням gets
.
Альтернативи
Замість 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)
відкидає його.
Безпека використання
Безпечне використання gets
вимагає від програміста перевірки того, чи не стане проблемою переповнення буфера. Стандарт мови Сі цього не гарантує; проте, існує кілька дещо ускладнених способів перевірити це з різним ступенем переносимості. Одним з можливих варіантів є захисна сторінка для захисту пам'яті. У поєднанні з обробниками винятків, такими як SIGSEGV
і , захисна сторінка може допомогти з обробкою помилок.
Примітки
- GNU. GNU Библиотека Си — Строковый Ввод. Архів оригіналу за 19 березня 2012. Процитовано 2 серпня 2008.
Функція
gets
дуже небезпечна, оскільки вона не забезпечує жодного захисту від переповнення рядкаs
. Бібліотека GNU включає її тільки заради сумісності. Вам слід завжди використовувати замість неїfgets
абоgetline
. - Чому всі кажуть не використовувати
gets()
?. comp.lang.c Часті питання. Архів оригіналу за 19 березня 2012. Процитовано 2 серпня 2008.(англ.) - gets(3) [ 24 березня 2022 у Wayback Machine.] — «Ніколи не використовуйте
gets()
. Оскільки неможливо сказати, не знаючи нічого про дані, скільки символів прочитаєgets()
, і томуgets()
продовжить поміщати символи в буфер і після його заповнення, що дуже небезпечно у використанні. Це може порушити інформаційний захист комп'ютерної системи.»
Посилання
- . pubs.opengroup.org. Архів оригіналу за 21 січня 2022. Процитовано 30 березня 2022.
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
gets funkciya sho vhodit do standartnoyi biblioteki movi Si ogoloshena v zagolovnomu fajli a href wiki Stdio h title Stdio h stdio h a yaka chitaye ryadok zi standartnogo vhidnogo potoku i pomishaye yiyi v bufer stvorenij funkciyeyu sho viklikaye Yaksho vidaye pomilku to teper dlya yiyi vikliku slid viklikati gets s RealizaciyaMozhna realizuvati takim sposobom za dopomogoyu getchar char gets char s ochishennya buferu vvedennya fflush stdin int i k getchar Povertayemo NULL yaksho nichogo ne vvedeno if k EOF return NULL Zchituyemo ta kopiyuyemo v bufer simvoli doki ne dosyagnemo kincya ryadka abo fajlu for i 0 k EOF amp amp k n i s i k k getchar Pri viyavlenni pomilki bufer rezultatu nepridatnij if k EOF amp amp feof stdin return NULL Nul terminuyemo j povertayemo bufer u razi uspihu Simvol perevedennya ryadka u buferi ne zberigayetsya s i 0 return s Programist povinen znati maksimum chisla simvoliv yaki gets maye prochitati shob upevnitisya sho vidilyayetsya bufer dostatnogo rozmiru Podibne nemozhlivo bez informaciyi pro dani Cya problema mozhe sprichinyati pomilki i vidkrivaye prostir dlya porushen komp yuternoyi bezpeki za dopomogoyu perepovnennya bufera Bagato dzherel radyat programistam nikoli ne vikoristovuvati gets u novih programah Zastosuvannya gets velmi zasudzhuyetsya Funkciyu zalisheno v standartah C89 i C99 zadlya zvorotnoyi sumisnosti Bezlich instrumentiv rozrobki PZ yak napriklad GNU ld vidaye poperedzhennya v razi viyavlennya pri komponuvanni kodu z vikoristannyam gets AlternativiZamist gets mozhna vikoristati inshi funkciyi ryadkovogo vvedennya sho dozvolit uniknuti pomilok pov yazanih z perepovnennyam bufera Najprostishim variantom bude a href wiki Fgets title Fgets fgets a Pri zamini kodu viglyaduchar buffer BUFFERSIZE gets buffer kodom viglyaduchar buffer BUFFERSIZE fgets buffer sizeof buffer stdin slid mati na uvazi sho viklik fgets buffer sizeof buffer stdin vidriznyayetsya vid gets buffer ne tilki zahistom vid perepovnennya bufera ale j tim sho fgets buffer sizeof buffer stdin zberigaye zavershalnij simvol perevedennya ryadka yaksho vvedennya ryadka zakinchuyetsya simvolom perevedennya ryadka todi yak gets buffer vidkidaye jogo Bezpeka vikoristannyaBezpechne vikoristannya gets vimagaye vid programista perevirki togo chi ne stane problemoyu perepovnennya bufera Standart movi Si cogo ne garantuye prote isnuye kilka desho uskladnenih sposobiv pereviriti ce z riznim stupenem perenosimosti Odnim z mozhlivih variantiv ye zahisna storinka dlya zahistu pam yati U poyednanni z obrobnikami vinyatkiv takimi yak a href wiki SIGSEGV title SIGSEGV SIGSEGV a i zahisna storinka mozhe dopomogti z obrobkoyu pomilok PrimitkiGNU GNU Biblioteka Si Strokovyj Vvod Arhiv originalu za 19 bereznya 2012 Procitovano 2 serpnya 2008 Funkciya gets duzhe nebezpechna oskilki vona ne zabezpechuye zhodnogo zahistu vid perepovnennya ryadka s Biblioteka GNU vklyuchaye yiyi tilki zaradi sumisnosti Vam slid zavzhdi vikoristovuvati zamist neyi fgets abo getline Chomu vsi kazhut ne vikoristovuvati gets comp lang c Chasti pitannya Arhiv originalu za 19 bereznya 2012 Procitovano 2 serpnya 2008 angl gets 3 24 bereznya 2022 u Wayback Machine Nikoli ne vikoristovujte gets Oskilki nemozhlivo skazati ne znayuchi nichogo pro dani skilki simvoliv prochitaye gets i tomu gets prodovzhit pomishati simvoli v bufer i pislya jogo zapovnennya sho duzhe nebezpechno u vikoristanni Ce mozhe porushiti informacijnij zahist komp yuternoyi sistemi Posilannya pubs opengroup org Arhiv originalu za 21 sichnya 2022 Procitovano 30 bereznya 2022