НАЗВА

fgetc, fgets, getc, getchar, gets, ungetc - функції для вводу символів і ланцюжків

СТИСЛИЙ ОГЛЯД

#іnclude <stdio.h>

іnt fgetc(FІLE stream);
**char
fgets(char s, int size, FІLE stream);
іnt getc(FІLE stream);
int getchar(void);
char
gets(char s);
іnt ungetc(іnt c, FІLE
stream);**

ОПИС

fgetc() зчитує наступний символ з потоку stream і повертає його перетвореним у unsigned char, зведенним до int, або константу EOF по досягненні кінця файлу або помилці.

getc() схожа на fgetc(), але вона може бути реалізованою як макрос, що оцінюватиме поступлення з потоку stream більше одного разу.

getchar() є тим самим що й getc(stdin).

gets() зчитує рядок з stdin і записує його у буфер, на який вказує покажчик s, поки не зустрінеться символ нового рядка або EOF, що замінюються на '\0'. Жодної перевірки на переповнення буфера не відбувається (дивіться ?**ВАДИ**| нижче).

fgets() зчитує щонайбільше size - 1 символів з stream і заносить їх у буфер, на який вказує покажчик s. Читання переривається якщо досягнуто EOF або символу нового рядка. Якщо зчитано символ нового рядка, то він заноситься в буфер. Наприкінці рядка завжди додається '\0' після останнього зчитаного знаку.

ungetc() заносить c назад у stream, і перетворюватиме у unsigned char, якщо це можливо у подальших операцій читання. Занесені назад символи будуть повертатися в зворотному порядку; гарантується тільки одне занесення символів.

Виклики функцій, описаних тут, можуть перемежовуватись одне з одним і з викликами до інших функцій вводу з бібліотеки stdio для того самого потоку вводу.

Стосовно неблокуючих функцій, подивіться ?unlocked stdio(3).

ПОВЕРНЕНІ ЗНАЧЕННЯ

fgetc(), getc() і getchar() повертають прочитаний символ як unsigned char, перетворений до int, або EOF при досягненні кінця файлу або помилці.

gets() і fgets() повертають при вдалому завершенні операції і NULL, якщо сталася помилка або досягнуто кінець файлу із, тоді як решта символів залишились непрочитаними.

ungetc() повертає c при вдалій операції або EOF у випадку помилки.

ВІДПОВІДНІСТЬ СТАНДАРТАМ

ANSI - C, POSIX.1

ВАДИ

Ніколи не застосовуйте gets(), тому що без попереднього знайомства з даними неможливо взнати, яку кількість символів отримає gets(), а також тому, що gets() продовжуватиме заносити символи в буфер навіть після досягнення його кінця, що дуже небезпечно. Ця функція використовується для злому систем. Замість неї скористайтеся fgets().

Hе рекомендовано чергувати виклики функцій вводу з бібліотеки stdio з низькорівневими викликами read() для дескриптора файлу, зв'язаного з потоком вводу; результат цього буде невизначеним і, швидше за все, не тим, що очікується.

Наступний кусочок коду демонструє випадок, коли програміст припускає, що рядок занадто довгий, якщо він не містить символ нового рядка:

             char buf[1024], *p;

             while (fgets(buf, sizeof(buf), fp) != NULL) {
                 if ((p = strchr(buf, '\n')) == NULL) {
                     fprintf(stderr, "input line too long.\n");
                     exit(1);
                 }
                 *p = '\0';
                 printf("%s\n", buf);
             }

Не дивлячись на те, що помилка буде дійсною, якщо рядок перевишуватиме 1023 знаки, вона не справдиться у двох інших випадках:

  1. Якщо останній рядок у файлі не містить символа нового рядка, то рядок, який поверне fgets() не міститиме також. Тож strchr() поверне NULL і програма завершить свою дію, навіть якщо рядок був чинним.
  2. Всі пов'язані з рядками функції у C, strchr() включно, правильно припускають що кінець ланцюжка вказується як знак NULL ('\0'). Якщо б першим повернутим знаком був '\0', strchr() би негайно повернула значення і завершила програму, без розгляду решти вводу, у якому дійно міг знаходитись знак нового рядка.

Можливо функція ?fgetln(3) підходить краще для випадків небезпечного вводу.

ДИВІТЬСЯ ТАКОЖ

?read(2), ?write(2), ?fopen(3), ?fread(3), scanf(3), ?puts(3), ?fseek(3), ?ferror(3)


Перклав Віталій Цибуляк vi@uatech.atspace.com