Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯП - ПОИТ (Бахтизин) часть 1 редакт.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.76 Mб
Скачать

10. Файлы

10.1. Общие сведения

Файл – это именованная область, хранящая данные (программа или любая другая информация) на каком-либо носителе (дискета, винчестер, CD). Файл, как и массив, – это совокупность данных, потому они немного похожи. Различия:

  1. Файлы, в отличие от массивов, располагаются не в оперативной памяти, а на жестких дисках или на внешних носителях. Хотя файл может располагаться на так называемом электронном диске (в оперативной памяти).

  2. Файл не имеет фиксированной длины, т.е. может увеличиваться и уменьшаться.

  3. Перед работой с файлом его необходимо открыть, а после работы – закрыть.

Файлами в языке Си могут быть любые устройства, начиная с файла на дискете, винчестере и заканчивая, к примеру, принтером.

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

Существует два основных режима доступа к файлу:

  1. Текстовый

  2. Бинарный (двоичный)

Текстовые форматы представляют данные как простой текст доступный пользователям.

В общем случае текстовые файлы состоят из обычных печатных символов, а также пробелов, символов новой строки, и, возможно, символов табуляции.

В текстовом файле, например, число 1850 представлено четырьмя символами 1,8,5,0, которые идут друг за другом подобно строке “1850”. В коде ASCII эти четыре символа имеют представление 0x31 0x38 0x35 0x30 соответственно.

С другой стороны, в двоичном файле данных величины записываются таким способом, каким они хранятся в памяти. Поэтому попытки просмотреть или обработать двоичный файл при помощи обычного текстового редактора приводит к полной бессмыслице.

К примеру, то же число 1850 будет представлено как 0х073а, т.е. байтами 0х07 и 0х3a .

Поясним на примере, как это число будет записано в бинарном файле и как в текстовом.

На рис. 10.1 представлена целая величина 1850 как ASCII строка в текстовом файле и как двухбайтовая величина в двоичном файле, используя порядок от младших байтов к старшим.

Рис. 10.1. Представление целой величины 1850

EOF – признак конца файла.

Таким образом, видно, что в нашем случае бинарный файл требует меньше места, чем текстовый. Но это вовсе не означает, что необходимо использовать только бинарные файлы. Бывают случаи, когда текстовые файлы выглядят более предпочтительными. К примеру, если необходимо, чтобы пользователь мог сразу просмотреть результаты выполнения программы. Т.е. мог открыть файл текстовым редактором, не загружая специальную программу.

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

10.2. Открытие и закрытие файлов

Для открытия файла используется функция fopen(), которая при успешном открытии возвращает указатель на структуру типа FILE.

Этот указатель называется указателем на файл. Структура FILE связана с физическим файлом и содержит всю необходимую информацию для работы с ним (указатель на текущую позицию в файле, тип доступа и др.).

typedef struct

{

short level; // Число оставшихся в буфере

// непрочитанных байт. Буфер обычно

// имеет размер 512 байт. Как только

// level равен 0, в буфер (в ОП) из

// файла читается следующий блок

// данных

unsigned flags; // Флаг статуса файла: чтение,

// запись, дополнение

char fd; // Дескриптор файла

// (число определяющее номер файла)

unsigned char hold; // Непереданный символ

// (ungetc-символ)

short bsize; // Размер внутреннего промежуточного

// буфера

unsigned char buffer; // Значение указателя для доступа

// внутри буфера: задаёт начало

// буфера, начало строки или текущее

// значение указателя внутри буфера в

// зависимости от режима буферизации

unsigned char * curp; // Текущее значение указателя для

// доступа внутри буфера: задаёт

// текущую позицию в буфере для

// обмена с программой

unsigned istemp; // Флаг временного файла

short token; // Флаг сбоя при работе с файлом

} FILE; // Описание структуры FILE.

Возвращаемое функцией fopen() значение нужно сохранить и использовать при дальнейшей работе с открытым файлом.

Если произошла ошибка при открытии файла, то возвращается NULL.

Никогда не изменяйте указатель на файл! Это может привести к непредвиденным результатам.

Функция открытия файла fopen() принимает два параметра, оба являются указателями на строку. Как уже говорилось выше, строковые литералы (строки, строковые константы) также представляют собой указатели на строки, т.е. возможно их использование в качестве параметров этой функции.

FILE *fopen(char *filename, char *mode);

Здесь filename – указатель на строку, содержащую имя открываемого файла, при необходимости – с путём к нему (строка оформляется по правилам MS-DOS); mode – указатель на строку, описывающую режим открытия.

Пример записи:

...

FILE *p;

p = fopen(“1.doc”, ”r+b”); // в качестве пути к файлу

// используется литерал

или

char *s = ”1.doc”;

p = fopen(s, ”r+b”); // в качестве пути к файлу используется

// указатель на строку

...

Объявление нескольких файловых переменных следует делать с большой долей внимательности.

К примеру, такое объявление

...

FILE *p, p1;

...

будет неверным, так как р1 будет переменной типа FILE, а не указателем.

В таблице 10.1 приведены возможные режимы открытия файла.

Таблица 10.1. Режимы открытия файлов

“r”

Открыть файл для чтения. Файл должен существовать

“w”

Открыть файл для записи. Если файл существует, то его содержимое теряется. Если нет – файл создается.

“a”

Открыть файл для записи в конец файла. Если файл не существует, то он создается.

“r+”

Открыть файл для записи и чтения. Файл должен существовать.

Содержимое файла не теряется.

“w+”

Открыть файл для чтения и записи. Если файл не существует, то он создается. Если файл существует, то его содержимое теряется.

“а+”

Открыть файл для записи и чтения в конец файла. Если файл не существует, то он создается.

К комбинациям вышеперечисленных литералов могут быть добавлены также "t" либо "b":

"t" Открыть файл в текстовом режиме.

"b" Открыть файл в бинарном режиме.

Возможны следующие режимы доступа:”w+b”, “wb+”, “rw+”, “w+t”и т.д.

После работы с файлом, файл должен быть закрыт функцией fclose(). Для этого необходимо в указанную функцию передать указатель на структуру FILE (указатель на файл), который был получен при открытии функцией fореn().

Если программа завершает работу нормально, т.е. либо main() возвращает управление операционной системе, либо вызывается exit(), то все файлы закрываются автоматически.

В случае аварийного завершения работы программы, например в случае краха или вызова функции abort() , файлы не закрываются.

Пример закрытия:

...

FILE *p;

...

fclose(p);

...

Приведем пример программы, открывающей файлы для записи и чтения в текстовом режиме.

#include <stdio.h> // подключаем заголовочный файл для работы

// функций printf(), scanf()

Void main(void)

{

FILE *in; // указатель на структуру FILE

if ((in = fopen("d:\\ex1_in.txt", "rt")) == NULL)

// файл d:\ex1_in.txt должен существовать

// открывается файл для чтения

// eсли файл не существует, то fopen() вернет NULL и

// осуществится выход из программы

{

printf("Невозможно открыть входной файл.\n");

return;

}

else

printf(" Входной файл открыт \n");

fclose(in);

}

Далее приведен пример программы открытия файлов в бинарном режиме.

#include <stdio.h>

void main(void)

{

FILE *in;

if ((in = fopen("d:\\ex1_in.txt", "rb")) == NULL)

// файл d:\ex1_in.txt должен существовать

{

printf("Невозможно открыть входной файл.\n");

return;

}

else

printf("Входной файл открыт \n");

fclose(in);

}