ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4289
Скачиваний: 28
Г Л А В А
30
Функции для работы
с файлами <stdio.h>
30.1. Файлы и потоки
Файлом
называют последовательность однотипных данных, хра-
нящихся на внешнем носителе информации. Под
доступом к
файлу
понимают запись и чтение данных из файла.
Потоком
на-
зывается логический или, другими словами, программный ин-
терфейс, который обеспечивает доступ к файлу. Прежде чем ис-
пользовать поток для доступа к файлу, его необходимо соединить
с этим файлом, т. е. обеспечить поток информацией о файле. Эта
информация хранится в структуре типа
FILE
. Потому считается,
что поток имеет тип
FILE*
, т. е. является указателем. Когда поток
соединяют с файлом, то говорят, что
файл открывают
. Когда
поток отсоединяют от файла, то говорят, что
файл закрывают
.
Каждый поток может работать в двух режимах: текстовом и би-
нарном. Режим работы потока задается при его соединении с
файлом.
В текстовом режиме поток записывает и читает из файла тексто-
вые строки, которые заканчиваются символом
\n
(переход на но-
вую строку) и могут содержать символ
\t
(табуляция). По стан-
дарту поток должен обеспечивать обработку строк длиной не ме-
нее 254 символа, включая символ
\n
. Стандартом допускается,
что при чтении и записи данных текстовым потоком может про-
исходить их преобразование.
Часть III. Стандартная библиотека языка программирования C
342
В бинарном режиме поток записывает и читает данные из файла в
том виде, в котором они хранятся в оперативной памяти.
Поясним подробнее разницу между текстовым и бинарным ре-
жимами работы потока. Как в текстовом, так и в бинарном режи-
ме можно использовать все функции для доступа к файлу. При
работе в бинарном режиме поток записывает на диск точные ко-
пии данных из оперативной памяти и считывает в оперативную
память точные копии данных с диска. Работа потока в текстовом
режиме отличается от работы потока в бинарном режиме тремя
моментами.
Во-первых, в этом случае комбинация символов <Ctrl>+<Z> ин-
терпретируется как конец файла.
Во-вторых, при записи в текстовый поток комбинации символов
\r
(возврат каретки) и
\n
в файл записывается только символ
\n
.
А при чтении из текстового потока символ
\n
наоборот преобра-
зуется в комбинацию символов
\r\n
.
В-третьих, т. к. при записи в текстовый поток может происходить
преобразование количества и представления символов, то для
получения позиции в файле, связанном с текстовым потоком,
нужно использовать только функции
fgetpos
и
ftell
.
Из вышеизложенного следует, что файлы не являются бинарны-
ми или тестовыми, такие характеристики присущи потокам. По-
этому к каждому файлу можно получить доступ как с помощью
бинарного, так и текстового потока. Но, для того чтобы избежать
ошибок, связанных с неправильным доступом к файлу, следует
придерживаться следующего правила: не нужно смешивать би-
нарный и текстовый потоки при доступе к одному файлу. Если
данные в файл записывались бинарным потоком, то и читать эти
данные из файла следует также бинарным потоком. Это же заме-
чание справедливо и для текстовых потоков.
В следующих разделах будут описаны стандартные функции для
работы с файлами, используемые в языке программирования С.
Глава 30. Функции для работы с файлами <stdio.h>
343
30.2. Открытие файла
Для соединения потока с файлом используется функция
fopen
,
которая имеет следующий прототип:
FILE* fopen(const char* filename, const char* mode);
Эта функция открывает файл, имя которого задано параметром
filename
, в режиме, заданном параметром
mode
. В случае успеш-
ного завершения функция
fopen
возвращает указатель на поток, а
в случае неудачи —
NULL
.
Параметр
mode
может принимать следующие значения:
"r"
— чтение в текстовом режиме;
"w"
— запись в текстовом режиме;
"a"
— присоединение в текстовом режиме;
"rb"
— чтение в бинарном режиме;
"wb"
— запись в бинарном режиме;
"ab"
— присоединение в бинарном режиме;
"r+"
,
"w+"
или
"a+"
— чтение и запись в текстовом режиме;
"r+b"
,
"w+b"
или
"a+b"
— чтение и запись в бинарном режиме;
"rb+"
,
"wb+"
или
"ab+"
— чтение и запись в бинарном режиме.
При открытии файла в режимах
"r"
,
"rb"
,
"r+"
или
"r+b"
его ин-
дикатор позиции устанавливается на начало файла. В случае если
открывается несуществующий файл, то функция
fopen
заканчи-
вается неудачей.
При открытии файла в режимах
"w"
,
"wb"
,
"w+"
или
"w+b"
создает-
ся новый файл. Если файл с заданным именем существует, то его
содержимое стирается, а индикатор позиции устанавливается на
начало файла.
При открытии файла в режимах
"a"
,
"ab"
,
"a+"
или
"a+b"
создает-
ся новый файл. Если файл с заданным именем существует, то он
открывается, и индикатор позиции устанавливается на конец
файла.
Следует учитывать, что если текстовый файл открывается в ре-
жиме чтения и записи, то базовая операционная система может
Часть III. Стандартная библиотека языка программирования C
344
открыть его в бинарном режиме. Максимальное количество фай-
лов, которые можно открыть одновременно задается макросом
FOPEN_MAX
. Максимальная длина имени файла задается макросом
FILENAME_MAX
.
30.3. Перенаправление потока
Для перенаправления потока используется функция
freopen
, ко-
торая имеет следующий прототип:
FILE* freopen(const char* filename,
const char* mode, FILE* stream);
Эта функция закрывает файл, соединенный с потоком
stream
, и
соединяет с этим потоком файл
filename
в режиме
mode
. В случае
успеха функция возвращает указатель на поток, а в случае неуда-
чи —
NULL
. Параметр
mode
может принимать те же значения, что и
в функции
fopen
.
30.4. Закрытие файла
Для отсоединения потока от файла используется функция
fclose
,
которая имеет следующий прототип:
int fclose(FILE* stream);
Эта функция закрывает файл, при этом освобождая все буферы
потока. При успешном завершении функция возвращает
0
, а в
случае неудачи — значение
EOF
(End Of File, конец файла).
30.5. Работа с индикатором ошибки
С каждым потоком связан индикатор ошибки, который находится
в установленном положении, если в потоке, связанном с файлом,
произошла ошибка. В противном случае индикатор ошибки на-
ходится в сброшенном состоянии. Для работы с индикатором
ошибки используются функции
ferror
и
clearerr
.
Функция
ferror
имеет следующий прототип:
int ferror(FILE* stream);
Глава 30. Функции для работы с файлами <stdio.h>
345
Эта функция возвращает ненулевое значение, если индикатор
ошибки установлен, в противном случае возвращает
0
.
Функция
clearerr
имеет следующий прототип:
void clearerr(FILE* stream);
Эта функция сбрасывает индикаторы ошибки и конца файла для
потока
stream
.
30.6. Работа
с индикатором конца файла
Структура
FILE
содержит индикатор конца файла, который уста-
навливается в ненулевое значение функцией чтения из файла при
достижении этой функцией конца файла. Состояние конца файла
читается функцией
feof
, которая имеет следующий прототип:
int feof(FILE* stream);
Эта функция возвращает ненулевое значение, если индикатор
конца файла установлен, в противном случае функция возвраща-
ет
0
.
30.7. Работа
с индикатором позиции файла
Для каждого файла, после его открытия, определяется индикатор
позиции, который указывает на смещение от начала файла в бай-
тах. Тип индикатора позиции обычно определяется как
typedef long fpos_t;
Для работы с индикатором позиции предназначены следующие
функции
rewind
,
fseek
,
fsetpos
и
fgetpos
.
Функция
rewind
имеет следующий прототип:
void rewind(FILE* stream);
Эта функция устанавливает индикатор позиции на начало файла,
связанного с потоком
stream
. При этом сбрасываются индикато-
ры ошибки и конца файла.