Организация работы с файлами
Понятие потока
Язык Си, кроме стандартного ввода данных с клавиатуры и вывода результатов на экран, предоставляет также возможность обмена при операциях ввода/вывода с внешними устройствами, в том числе, с файлами на диске.
В Си не предусмотрены никакие предопределенные структуры файлов (такие как последовательного или прямого доступа). Все файлы рассматриваются как последовательности, потоки байтов.
Поток- это источник или приемник данных. Его можно связать с каким- либо внешним устройством, например, с принтером, клавиатурой, диском и т.д.
В языке Си определены два вида потоков: текстовый и бинарный.
Текстовый поток - это последовательность строк. Каждая строка содержит нуль и более символов и обязательно заканчивается символом – терминатором новая строка '\n'.
Бинарный или двоичный поток - это последовательность двоичных кодов (байтов), как правило, используемая для запоминания кодов машинного языка.
Поток соединяется с файлом или другим устройством посредством его открытия. Эта связь разрывается путём закрытия потока.
Открытие потока осуществляется функцией fopen(), а закрытие – функцией fclose().
Когда программа начинает работу, то автоматически открываются три потока: stdin, stdout, stderr.
STDIN –стандартный входной поток (по умолчанию связан с клавиатурой).
STDOUT – стандартный выходной поток (по умолчанию связан с экраном монитора).
STDERR – поток стандартных ошибок (связан с экраном монитора).
Открытие файла
Для того, чтобы связать программу с файлом на диске, необходимо определить в программе переменную типа указатель на файл:
FILE *fp;
где FILE – это структура, определённая в <stdio.h> с помощью средства typedef и содержащая некоторую информацию о файле.
После того, как указатель на файл описан, его можно связать с конкретным файлом в момент открытия данного файла. Открыть файл можно с помощью следующей конструкции:
fp = fopen (“ имя_ файла”, “ режим_ доступа”);
Константы в круглых скобках имеют следующий смысл:
имя_файла – это параметр, характеризующий имя и тип используемого файла на диске, например, “test.txt”;
режим доступа – это параметр, характеризующий как должен использоваться данный файл. Этот параметр может принимать следующие значения:
’r’ -файл открывается для чтения (файл должен существовать на диске);
’w’ - файл открывается для записи; если файла с указанным именем нет, то он создаётся; если файл существует, то старое содержимое файла уничтожается;
’а’ - файл открывается, либо создаётся для дозаписи в конец файла;
’r+’ – файл открывается для чтения и записи (файл должен существовать).
’w+’ – файл открывается для чтения и записи; старое содержимое, если файл существовал, теряется.
’а+’ – файл открывается, либо создаётся для чтения уже существующей информации и добавления новой в конец файла.
Обычно по умолчанию файл считается текстовым, однако можно явно указать с каким файлом будет работать программа: текстовым (t) или бинарным (b), например:
r + t, w + b, at, wt +, и т. д.
Операцию открытия файла можно записать и так:
FILE *fp = fopen (‘test. txt’, ‘w’);
Теперь указатель fp будет связан с файлом на диске с именем ‘test.txt’. Во всех операциях с файлом теперь следует указывать fp.
Закрытие файла
После того, как работа с файлом закончена, его следует закрыть. Операция закрытия файла имеет вид:
fclose (имя файла), например: fclose (fp);
Так как операции с файлами осуществляются посредством промежуточной буферизации, то операция закрытия осуществляет выталкивание содержимого буфера.
Если операции закрытия файла в программе нет, то по окончанию программы все открытые файлы будут закрыты автоматически. Следует, однако, помнить, что настройка среды ограничивает число одновременно открытых файлов, поэтому следует явно определять операцию их закрытия.
8.4. Операции ввода/вывода в файл (из файла)
Различают следующие операции ввода/вывода:
- ввод-вывод отдельных символов;
- построчный ввод-вывод;
- форматированный ввод-вывод;
- ввод/вывод объектов (данных простых и сложных типов).
Ввод-вывод отдельных символов. Эти операции осуществляются с помощью следующих функций:
1) getc() и fgetc() – ввод символа из файла;
2) puts() и fputc () – вывод символа в файл.
Разница между этими функциями заключается в том, что fgetc() и fputc() – это собственно функции, а getc() и putc() – это макросы.
В программе эти функции записываются следующим образом:
ch= fgetc (fp);
ch принимает значение символа из файла, на который указывает fp.
fputc (ch, fp); – значение символа ch выводится в файл, на который указывает fp.
Пример 8.1. Посимвольного копирования:
# include <stdio.h>
void main (void)
{
char ch;
FILE *ist, *pri;
if((ist = fopen(“text_1.txt”, “г”)) = =NULL)
{
printf (“Не могу открыть файл источник \ n”);
return;
}
if ((pri = fopen(“text_2.txt”,”w”)) = = NULL)
{
printf (“ Не могу открыть файл приемник \n”);
return;
}
while ((ch = fgetc(ist)) != EOF)
fputc(ch, pri);
fclose (ist);
fclose(pri);
}
Ввод/вывод строк. Операции ввода/вывода строк осуществляется с помощью функций fgets() и fputs () соответственно.
Функция fgets() имеет три аргумента:
char *fgets(s, n, stream),
где s- указатель на местоположение строки;
n- предельная длина считываемой строки;
stream- указатель на файл, который будет читаться.
Функция fputs() имеет два аргумента
int fputs(s, stream),
где s- указатель на местоположение строки символов, которая будет записываться в файл;
stream- указатель файла.
Пример 8.2: Считывание файла строка за строкой и копирование.
# include<stdio.h>
void main (void)
{
int n = 80;
char string[80];
FILE *fpr, *fis;
fis = fopen (“text_1”, “r”);
fpr = fopen (“text_ 2”, “w”);
while ((fgets(string, n, fis)) != NULL)
fputs(string, fpr);
fclose (fis);
fclose (fpr);
}
При достижении конца файла функция fgets возвращает NULL.
Форматированный ввод/вывод. Форматированный ввод/вывод осуществляется функциями fprintf() и fscanf(). Эти функции работают аналогично функциям printf() и scanf(). Разница заключается в дополнительном аргументе- ссылке на файл, с которым они работают. Этот аргумент указывается первым в списке.
Например:
# include <stdio.h>
void main (void)
{
FILE *fp;
int d;
fp = fopen (“file_1.dat”, “a+b”);
fscanf (fp, “%d”, &d);
fclose (fp);
fp = fopen (“file_2. dat”, “r+b”);
fprintf (fp,”%d”, d);
fclose (fp);
}
Здесь продемонстрировано повторное использование указателя на файл после закрытия файла.
Блочный ввод-вывод осуществляется функциями fread() и fwrite().
Определение:
fread (ptr, size, n_ obg, stream);
Читать из файла stream в массив ptr (указатель) не более n_obg объектов размером size.
fwrite (ptr, size, n_obg, stream);
Пишет из массива с указателем ptr n_obg объектов размера size в поток stream (файл).
Дата добавления: 2017-06-02; просмотров: 828;