9.1. Основные понятия

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

    • долговременного хранения данных;
    • доступа различных программ к одним и тем же данным;
    • обработки больших массивов данных, которые невозможно целиком разместить в оперативной памяти компьютера.

Файл, не содержащий ни одного элемента, называется пустым. Создается файл путем добавления новых записей в конец первоначально пустого файла. Длина файла, т.е. количество элементов, не задается при определении файла. При вводе и выводе данные рассматриваются как поток байтов. Физически поток – это файл или устройство (клавиатура или дисплей). В Си поток можно открыть для чтения и/или записи в текстовом или бинарном (двоичном) режиме. В текстовых файлах не употребляются первые 31 символ кодовой таблицы ASCII (управляющие), а символы конца строки 0x13 (возврат каретки, CR) и 0x10 (перевод строки LF) преобразуются при вводе в одиночный символ перевода строки \n (при выводе выполняется обратное преобразование). Эти символы добавляются в конце каждой строки, записываемой в текстовый файл. При обнаружении в текстовом файле символа с кодом 26 (0x26), т.е. признака конца файла, чтение файла в текстовом режиме заканчивается, хотя файл может иметь продолжение.

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

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

В заголовочном файле stdio.h содержится описание файлового типа FILE, с которым связывается файловая переменная (указатель на файл). При открытии файла указатель на файл связывается с конкретным файлом на диске и определяется режим открытия файла:

r (r+) - файл открывается для чтения (чтения и записи);

w (w+) - открывается пустой файл для записи (чтения и записи). Если файл с таким именем существует, он стирается;

a (а+)- файл открывается для дополнения в конец (чтения и дополнения).

Режим открытия может также содержать символы t (текстовый файл) и b (двоичный файл), указывающий на вид открываемого файла: rb, wb, ab, rt, wt, at, rb+, wb+, ab+ и т.д.

Закрытие файла (текстового или бинарного) выполняется функцией fclose(), установка указателя на начало файла - функцией rewind(). Если при попытке чтения данных из файла встречается символ конца файла, то возвращается специальное значение EOF. Функции feof(), ferror() сообщают о причинах, по которым операция ввода/вывода не выполнилась. Запись данных в файл и чтение данных из файла можно выполнять разными способами:

  1. функциями форматного ввода-вывода fscanf(), fprintf();
  2. функциями неформатного ввода-вывода fread(), fwrite().

Если требуется сохранять и восстанавливать числовые данные без потери точности, то лучше использовать fread(), fwrite(). Если обрабатывается текстовая информация, которая будет просматриваться обычными текстовыми редакторами, то используется fgetс()- посимвольное чтение файла, посимвольная запись в файл - fputc() или функции fscanf(), fprintf(). Для чтения из файла и записи в файл строки используются функции fgets() и fputs().

 

9.2. Текстовые файлы

Пример программы с использованием текстовых файлов

Создать текстовый файл "new1.txt" записав в него строку из 50 символов. Все символы, отличные от пробела, переписать в новый файл "new2.txt":

#include <stdio.h>

#include <conio.h>

#include <string.h>

main()

{char ch, sl[50];

 char text[]="one to tree four";

 FILE *pf, *pr; // Указатели на файлы

 pf=fopen("new1.txt","w"); // Создание нового файла new1.txt

 clrscr();

 fprintf(pf,"%s\n",text); // Запись в файл строки text

 fclose(pf); // Закрытие файла pf

 pf=fopen("new1.txt","r"); // Открытие файла pf для чтения

 pr=fopen("new2.txt","w"); // Создание нового файла new2.txt

 while (!feof(pf)) // Пока не конец файла

 {
    ch=getc(pf); // Чтение символа ch из файла pf

    if (ch != ' ')

       putc(ch,pr); // Запись в файл pr символа ch

 }

 fclose(pr); // Закрытие файла pr

 rewind(pf); // Возврат указателя на начало файла pf

 fgets(sl,50,pf); // Чтение из файла pf строки в переменную sl

 printf("%s\n",sl); // Вывод строки sl на дисплей

 pr=fopen("new2.txt","r"); // Открытие файла pr для чтения

 while (!feof(pr)) // Пока не конец файла pr

 {
     ch=getc(pr); // Чтение символа из файла pr

     putchar(ch); // Вывод символа ch на дисплей

 }

 fclose(pf); // Закрытие файлов

 fclose(pr);

 getch();

}

При чтении текстовых файлов лучше использовать функции getc или fgets, так как при использовании fscanf (pr, “%s”, sl) читается только очередное слово до пробела или символа табуляции и требуется повторение этой функции многократно для других слов.

 

9.3. Контрольные вопросы

1. Чем отличается файл от массива?

2. Особенности организации текстовых файлов.

3. Что понимается под чтением, и что под записью в файл?

4. Какие функции можно применять для записи в файл?

5. Какие функции можно применять для чтения из файла?