Хрестоматия по программированию на Си в Unix


Работа с файлами. Хрестоматия по программированию на Си в Unix - стр. 7


Отметим, что в UNIX признак конца файла в самом файле физически НЕ ХРАНИТСЯ. Система в любой момент времени знает длину файла с точностью до одного байта; признак EOF

вырабатывается стандартными функциями тогда, когда обнаруживается, что указатель чтения достиг конца файла (то есть позиция чтения стала равной длине файла - последний байт уже прочитан).

В MS DOS же в текстовых файлах признак конца (EOF) хранится явно и обозначается символом CTRL/Z. Поэтому, если программным путем записать куда-нибудь в середину файла символ CTRL/Z, то некоторые программы перестанут "видеть" остаток файла после этого символа!

Наконец отметим, что разные функции при достижении конца файла выдают разные значения: scanf, fscanf, fgetc, getc, getchar выдают EOF, read - выдает 0, а gets, fgets - NULL.

Напишите программу, которая запрашивает ваше имя и приветствует вас. Для ввода имени используйте стандартные библиотечные функции

gets(s); fgets(s,slen,fp);

В чем разница?

Ответ: функция gets() читает строку (завершающуюся '\n') из канала fp==stdin. Она не контролирует длину буфера, в которую считывается строка, поэтому если строка окажется слишком длинной - ваша программа повредит свою память (и аварийно завершится). Единственный возможный совет - делайте буфер достаточно большим (очень туманное понятие!), чтобы вместить максимально возможную (длинную) строку.

Функция fgets() контролирует длину строки: если строка на входе окажется длиннее, чем slen символов, то остаток строки не будет прочитан в буфер s, а будет оставлен "на потом". Следующий вызов fgets прочитает этот сохраненный остаток. Кроме того fgets, в отличие от gets, не обрубает символ '\n' на конце строки, что доставляет нам дополнительные хлопоты по его уничтожению, поскольку в Си "нормальные" строки завершаются просто '\0', а не "\n\0".

char buffer[512]; FILE *fp = ... ; int len; ... while(fgets(buffer, sizeof buffer, fp)){ if((len = strlen(buffer)) && buffer[len-1] == '\n') /* @ */ buffer[--len] = '\0'; printf("%s\n", buffer); }




- Начало -  - Назад -  - Вперед -



Книжный магазин