1.11M
Категория: ПрограммированиеПрограммирование

Лекция_12_ОАИП_2020 (1)

1.

Работа с файлами.
Лекция №12
Лектор: Романькова Татьяна Леонидовна
02.05.2026
1

2.

Понятие файла
Файл — именованная область данных на носителе
информации, используемая как базовый объект взаимодействия с
данными в операционных системах..
Язык СИ рассматривает любой файл как последовательный
поток байтов. Каждый файл заканчивается или маркером конца
файла, или особым байтом, определённым в работающей с
файлами программе.
С этой точки зрения в языке программирования C файлом
может быть как собственно файл на жестком диске, так и
принтер, дисплей и другие подключаемые устройства вводавывода.
Перед работой с файлом его необходимо открыть, а после
работы – закрыть.
Различают два вида файлов: текстовые и бинарные.
02.05.2026
2

3.

Текстовые файлы могут быть просмотрены и
отредактированы с клавиатуры любым текстовым редактором и
представляют собой последовательность ASCII-символов.
Эта последовательность символов разбивается на строки,
каждая из которых заканчивается двумя кодами: 13, 10:
символами возврат каретки (CR) и перевод строки (LF).
Примеры расширений текстовых фалов: *.bat, *.c, *.asm, *.срр.
Бинарные файлы – это файлы, которые не имеют
структуры текстовых файлов. Каждая программа для своих
бинарных файлов определяет собственную структуру.
Текстовые файлы являются подмножеством двоичных файлов,
но в отличие от двоичных не могут содержать весь набор
символов.
Библиотека языка C содержит функции для работы как с
текстовыми, так и с бинарными файлами. Для их применения в
программе необходимо подключить заголовочный файл stdio.h.
02.05.2026
3

4.

Открытие потока
Перед работой с файлом, его необходимо открыть. Функция
открытия файла fopen():
FILE* fopen(char *filename, char *mode);
Первый параметр задает физическое местонахождение
(путь) и имя открываемого файла, а второй задает режим доступа,
от которого зависит, как файл может быть обработан.
Функция возвращает указатель на структуру, которая
имеет тип FILE, определенный в stdio.h.
Структура FILE содержит всю необходимую информацию
для работы с файлом (указатель на текущую позицию в файле,
тип доступа и др.).
02.05.2026
4

5.

struct _iobuf
{
char* _ptr;
int
_cnt;
char* _base;
int
_flag;
int
_file;
int
_charbuf;
int
_bufsiz;
char* _tmpfname;
};
typedef struct _iobuf FILE;
Второй параметр mode, который определяет тип доступа к
файлу, может принимать значения:
"w": текстовый файл открывается для записи. Если файл
существует, то он пересоздается и записывается заново
"r": текстовый файл открывается для чтения.
"a": текстовый файл открывается для добавления в него новых
данных. Если файл существует, то данные просто добавляются.
02.05.2026
5

6.

"w+": создает текстовый файл для чтения/записи. Если файл
существует, то он пересоздается;
"r+": текстовый файл открывается для чтения/записи. Запись
допустима в любом месте файла, кроме конца файла, то есть
недопустимо увеличение размеров файла.
"a+": текстовый файл открывается или создается (при его
отсутствии) для чтения/записи. В отличие от режима w+ файл при
открытии не пересоздается заново, а в отличии от режима r+
можно записывать данные в конец файла
К комбинациям перечисленных литералов могут быть
добавлены также " t " либо " b " :
" t " - файл в текстовом режиме.
" b " - файл в бинарном режиме.
02.05.2026
6

7.

"wb": бинарный файл открывается для записи
"rb": бинарный файл открывается для чтения
"ab": бинарный файл открывается для дозаписи
"w+b": бинарный файл создается для записи/чтения
"r+b": бинарный файл открывается для чтения/записи
"a+b": бинарный файл открывается или создается (при его
отсутствии) для чтения/дозаписи
Если режим не указан, то файл открывается в текстовом
режиме.
Замечание: порядок, в котором заданы литеры b и +, не имеет
значения. Строка rb+ равносильна строке r+b
02.05.2026
7

8.

Если при выполнении функции fopen
произошла
ошибка при открытии файла, то возвращается NULL.
Причины могут быть разные. Например:
- файл не существует;
- отсутствие места на носителе;
- использование запретного по правилам ОС имени;
- аппаратный сбой и т.д.
Для вывода ошибки на консоль можно применять
встроенную функцию perror().
02.05.2026
8

9.

Закрытие файла
После работы с файлом он должен быть закрыт функцией
fclose(). Для этого необходимо в указанную функцию передать
указатель на FILE, который был получен при открытии функцией
fopen().
int fclose(FILE* filePtr);
Функция fclose() разрывает связь указателя с файлом и
закрывает его к дальнейшему использованию, до тех пор пока
он вновь не будет используя функцию fopen().
Функция возвращает число: 0 - в случае успешного
выполнения и встроенное значение EOF (-1) в случае ошибки.
При завершении программы незакрытые файлы автоматически
закрываются системой
02.05.2026
9

10.

Функции fopen() и fclose() являются функциями
потокового ввода-вывода и работают с файлами с
буферизацией.
Под буферизацией понимают, что вводимые и выводимые
данные запоминаются во временной области памяти, называемой
буфером.
При чтении из файла блок данных фиксированной длины
(обычно длина представляет степень двойки - 256 или 512 байт)
помещается в буфер операционной системы, а затем побайтно
передается приложению.
При записи в файл данные накапливаются в буфере, а при
заполнении буфера записываются на диск в виде единого блока
байт.
При закрытии файла с помощью fclose(), происходит освобождение
всех буферов, связанных с этим файлом, даже частично
заполненных, и информация записывается в файл.
02.05.2026
10

11.

Чтение и запись текстовых файлов
Функции для работы с текстовым файлом: fprintf(),
fscanf(), fgets(), fputs(). Формат параметров этих функций очень
похож на формат функций printf(), scanf(), gets() и puts(). Схожи
не только параметры, но и действия. Отличие в том, что printf(),
scanf() и другие работают по умолчанию с консолью (экран,
клавиатура), а fprintf(), fscanf() – с файлами (в том числе и со
стандартными потоками stdin, stdout и др.), поэтому у них
добавлен параметр, являющийся указателем на структуру FILE.
Функция fgets() считывает из файла одну строку и имеет
следующий прототип:
char* fgets(char* string, int length, FILE* fi);
Функция gets() заменяет символ \n на \0, а fgets()
сохраняет \n в считанной строке.
02.05.2026
11

12.

Функция прекращает работу после считывания символа
новой строки или после считывания символов, общим числом
length-1 (в зависимости от того, что произойдёт раньше). И в том и
в другом случае ‘\0’ добавляется в конец строки.
При успешном завершении функция возвращает указатель
string, а при ошибке или достижении конца файла возвращается
значение NULL.
Функция fputs() записывает строки символов в файл.
Прототип:
int fputs(const char* string, FILE* fi);
В
качестве
результата
функция
возвращает
неотрицательное целое число. При ошибках в процессе записи
возвращается значение EOF.
При записи строки нулевой символ '\0' в файл не записывается.
02.05.2026
12

13.

02.05.2026
13

14.

// чтение из файла
if ((fptr = fopen(fileName, "r")) == NULL)
{
perror("Ошибка открытия файла");
}
Функция perror() помещает значение глобальной переменной ERRNO в строку и
записывает эту строку в файл stderr. Если str имеет ненулевое значение, то
сначала выводится строка, а за ней следует двоеточие и сообщение об ошибке
else
{
// пока не будут прочитаны все данные, считываем по 256 байт
while ((fgets(str, 256, fptr)) != NULL)
{
printf("%s", str);
}
fclose(fptr);
}
02.05.2026
14

15.

Функция exit() завершает вызванный процесс, то есть
программу (функцию main()).
Особенностью функции exit() является то, что она
закрывает любые файлы, открытые в программе. Аргументом
функции exit() является номер кода ошибки.
Для распознавания конца файла используется функция
feof()
Прототип функции feof() следующий:
int feof(FILE* stream);
Если достигнут конец файла, то feof() возвращает true (1); в
противном же случае эта функция возвращает NULL.
Использовать данную функцию можно как в работе с двоичными,
так и с текстовыми файлами.
02.05.2026
15

16.

Пример. Прочитать из текстового файла с данными в формате csv
информацию о собаках в массив структур
02.05.2026
16

17.

02.05.2026
17

18.

02.05.2026
18

19.

02.05.2026
19

20.

Форматируемый ввод-вывод
Функции fprintf() и fscanf() позволяют отформатировать
записываемые и считываемые данные соответственно.
Функция fprintf() имеет следующий прототип:
int fprintf(FILE* fi,char* format,<cписок значений>);
Строка форматирования и передача в нее значений
определяются также, как и в случае с функцией printf().
Пример. Записать информацию из массива структур в текстовый
файл в формате csv.
02.05.2026
20

21.

02.05.2026
21

22.

Функция fscanf() имеет следующий прототип:
int fscanf(fprintf(FILE* fi,char* format,<cписок аргументов>);
Функция возвращает числовое значение. Если достигнут
конец файла, то функция возвращает значение EOF.
Пример. Прочитать информацию о собаках из текстового файла
в массив структур.
02.05.2026
22

23.

23
02.05.2026

24.

Позиционирование в потоке
В каждом открытом файле есть указатель на текущую
позицию. Операция чтения-записи производится с текущей
позиции в потоке.
При открытии потока в режимах "r" и "w" указатель
текущей позиции устанавливается на начальный байт потока.
При открытии в режиме "a" указатель устанавливается в
конец файла сразу за последним байтом.
При выполнении операции чтения-записи указатель в
потоке перемещается на новую позиции в соответствии с числом
прочитанных или записанных байтов. Это последовательный
доступ к данным.
Функция
void rewind(FILE *)
устанавливает указатель на начало потока
02.05.2026
24

25.

Задание. Вывести содержимое текстового файла три раза.
02.05.2026
25

26.

Чтобы установить указатель на некоторую заданную
позицию в файле, используют стандартную функцию fseek,
которая позволяет выполнить чтение или запись данных в
произвольном порядке.
Прототип этой функции следующий:
int fseek(FILE *f, long size, int code);
Второй параметр этой функции представляет числовое
значение, которое указывает, на какое количество байт надо
переместить указатель. Это значение может быть отрицательным,
если необходимо в потоке вернуться назад.
Третий параметр задает начальную позицию, относительно
которой идет смещение. В качестве этого параметра можно
использовать одну из встроенных констант, определенных в
файле stdio.h:
02.05.2026
26

27.

смещение от начала файла
0
(SEEK_SET);
смещение от текущей позиции
1
(SEEK_CUR);
смещение от конца файла
2
(SEEK_END).
Доступ к файлу с использованием функции позиционирования это произвольный доступ.
Если перемещение указателя было успешно выполнено, то
функция fseek() возвращает 0, иначе она возвращает ненулевое
значение.
Смещение может быть как положительным, так и
отрицательным, но нельзя выходить за пределы файла.
Чтобы определить текущее положение в файле, используют
функцию со следующим описанием:
long ftell(FILE *f);
возвращает значение указателя на текущую позицию в файле
или –1 в случае ошибки.
02.05.2026
27

28.

02.05.2026
28

29.

02.05.2026
29

30.

02.05.2026
30

31.

02.05.2026
31
English     Русский Правила