Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СИ.docx
Скачиваний:
6
Добавлен:
25.09.2019
Размер:
227.33 Кб
Скачать

[Править]Закрытие потока при помощи fclose

Функция fclose принимает один аргумент: указатель на структуру FILE потока для закрытия.

int fclose(FILE *fp);

Функция возвращает нуль в случае успеха и EOF в случае неудачи. При нормальном завершении программы функция вызывается автоматически для каждого открытого файла.

[Править]Чтение из потока [править]при помощи fgetc

Функция fgetc применяется для чтения символа из потока.

int fgetc(FILE *fp);

В случае успеха, fgetc возвращает следующий байт или символ из потока (зависит от того, файл «двоичный» или «текстовый» (как выше обсуждалось). В противном случае, fgetc возвращает EOF. (Отдельный тип ошибок можно определить вызовом ferror или feof с указателем на файл.)

Стандартный макрос getc также определен в <stdio.h>, успешно работая как fgetc, кроме одного: будучи макросом, он может обрабатывать свои аргументы более одного раза.

Стандартная функция getchar также определена в <stdio.h>, она не принимает аргументов, и эквивалентна getc(stdin).

[Править]«Ловушка» eof

Распространенной ошибкой является использование fgetc, getc или getchar для присваивания результата переменной типа char перед сравнением его с EOF. Следующий фрагмент кода демонстрирует эту ошибку, а рядом приведен корректный вариант:

Ошибка

Правильно

char c;

while ((c = getchar()) != EOF) {

putchar(c);

}

int c;

while ((c = getchar()) != EOF) {

putchar(c);

}

Нужно учитывать систему, в которой тип char, длина которого составляет 8 бит (в частности, архитектура x86), представляет 256 различных значений. getchar может возвращать любой из 256 возможных символов, а также может возвращать EOF для обозначения конца файла, значение которого не может совпадать ни с одним из значений char.

Когда результат getchar присваивается переменной типа char, которая может представить лишь 256 различных значений, происходит вынужденная потеря информации — при сжатии 257 значений в 256 «мест» происходит коллизия. Значение EOF при конвертации в char становится неотличимым от любого из остальных 256 символов. Если этот символ обнаружен в файле, код, приведенный выше, может принять его за признак конца файла, или, что еще хуже, если тип char — беззнаковый, тогда с учетом того, что EOF — значение отрицательное, оно никогда не сможет стать равным любому беззнаковому char, и таким образом, пример выше не закончится на метке конца файла, а будет выполняться вечно, повторно печатая символ, получающийся при конвертации EOF в char.

В системах, где int и char одинакового размера[каких?][источник не указан 512 дней], даже «правильный» вариант будет работать некорректно из-за сходства EOF и другого символа. Правильным вариантом обработки подобной ситуации является проверка feof и ferror после того, как getchar вернет EOF. Если feof определит, что конец файла еще не достигнут, а ferror «сообщит», что ошибок нет, то EOF, возвращенный getchar может считаться текущим символом. Такие дополнительные проверки делаются редко, так как большинство программистов считает, что их код никогда не будет выполняться на подобных системах с «большим char». Другой способ состоит в использовании проверки при компиляции, что UINT_MAX > UCHAR_MAX, которая хотя бы предотвратит компиляцию на подобных системах.