Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций -=Вычислительная техника и прог...docx
Скачиваний:
11
Добавлен:
01.05.2025
Размер:
2 Мб
Скачать
☆

6.2. Функции файлового ввода и вывода

Функции ввода и вывода содержатся в библиотеках, представленных на рис. 6.2.

Рисунок 6.2 — Функции ввода и вывода в языках С и С++

Примечание:

— файловый ввод и вывод осуществляется с помощью потокового ввода-вывода;

— перед работой с файлом необходимо открыть файловый поток;

— после работы с файлом необходимо закрыть файловый поток.

Файлы могут быть текстовые и бинарные. На рис. 6.3. представлены их основные отличия.

Рисунок 6.3 — Основные особенности текстовых и бинарных файлов

6.2.1. Файловый ввод и вывод средствами с

Формат объявления/открытия файлового потока:

FILE *имя_потока [ = fopen(const char *имя_файла,

const char *режим_открытия)] ;

Здесь:

режим_открытия — задает режим ввода/вывода:

r — файл открывается только для чтения;

w — файл создается только для записи (стирает предыдущий);

a — файл открывается для добавления данных в конец файла, чтение не разрешено;

r+ — существующий файл открывается для чтения и записи;

w+ — создается новый файл для чтения и записи (стирает предыдущий);

a+ — файл открывается для чтения и добавления данных в конец файла; если файл не существует, то он создается;

t — файл создается или открывается как текстовый (по умолчанию);

b — файл создается или открывается как бинарный.

При успешном открытии потока функция возвращает в программу указатель на структуру типа FILE, если поток открыть не удалось, то возвращает указатель на NULL.

Формат закрытия файлового потока:

fclose(*имя_потока) ;

Примечание:

— ввод/вывод в поток осуществляется через буферы;

— размеры буфера можно изменять с помощью функций setbuf и setvbuf;

— перед закрытием потока вся информация из буферов потока выгружается на диск;

— закрывать поток необходимо всегда, иначе возможна потеря данных.

Пример:

FILE *f_p = fopen (“myfile.txt”, “rt”);

…

fclose (f_p) ;

Примечания:

— при открытии файла на чтение/запись с ним связывается структура FILE. Данная структура содержит для каждого открытого файла счетчик положения текущей записи;

— сразу после открытия файла значение счетчика равно нулю;

— каждая операция ввода или вывода вызывает приращение счетчика.

Получить значение счетчика можно с помощью функций:

long int ftell (FILE *имя_потока) ;

long int fgetpos (FILE *имя_потока, *позиция_в_файле) ;

Примечание:

— функция ftell возвращает текущее значение счетчика в потоке;

— функция fgetpos возвращает значение текущей позиции счетчика в файле, который связан с потоком, и копирует значение счетчика по адресу *позиция_в_файле.

Установить значение счетчика можно с помощью функций fseek, fsetpos, fgetpos, rewind, fgetc.

Формат записи функции fseek:

int fseek (FILE *имя_потока, long смещение, int позиция) ;

Функция fseek — помещает текущую позицию в файле (счетчик) на величину ‘смещение’ в байтах относительно положения ‘позиция’:

SEEK_SET (= 0) — начало файла;

SEEK_CUR (= 1) — текущая позиция в файле;

SEEK_END (= 2) — конец файла.

Формат записи функции fsetpos:

int fsetpos (FILE *имя_потока, const позиция) ;

Функция fsetpos — перемещает текущую позицию в файле на позицию ‘позиция’, предварительно полученную с помощью функции fgetpos.

Формат записи функции rewind:

void rewind (FILE *имя_потока) ;

Функция rewind — устанавливает счетчик на начало потока и очищает флаги ошибок в потоке.

Формат функции ввода символа из файлового потока fgetc:

int fgetc (FILE *имя_потока) ;

Примечание:

— функция fgetc считывает символ из файлового потока;

— при удачном считывании символа возвращает в программу код символа;

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

Формат функции вывода символа в файловый поток fputc:

int fputc (int ch, FILE *имя_потока) ;

Примечание:

— функция fputc записывает символ ch в файловый поток;

— при удачной записи символа возвращает в программу код записанного символа;

— если произошла ошибка записи кода в поток, то в программу передается код 0xE0F.

Формат функции ввода строки символов из файлового потока fgets:

char* fgets (char *s, int N, FILE *имя_потока) ;

Примечание:

— функция fgets считывает не более N–1 байт из файлового потока в строку s;

— прекращает чтение, если встретился символ перехода на новую строку ‘\n’ или конец файла. Символ ‘\n’ не отбрасывается, а помещается в конец строки s. В переменную s добавляется символ конца строки ‘\0’;

— в случае успешного чтения функция передаёт в программу указатель на строку s;

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

Формат функции вывода строки символов в файловый поток fputs:

int fputs (const char *s, FILE *имя_потока) ;

Примечание:

— функция fputs записывает строку символов в поток;

— символ конца строки в поток не записывается;

— при ошибке записи в программу возвращается код 0xE0F, в противном случае — неотрицательное число.

Формат функции форматированного ввода из файлового потока fscanf:

int fscanf (FILE *имя_потока, const char *format [, a1, a2, …]) ;

Примечание:

— функция fscanf вводит из файлового потока строку аргументов a1, a2, … в формате, определенном строкой format;

— в программу функция передает количество переменных, которым присвоено значение;

— функция использует те же способы форматирования, что и функция scanf().

Формат функции форматированного вывода в файловый поток fprintf:

int fprintf (FILE *имя_потока, const char *format [, a1, a2, …]) ;

Примечание:

— функция fprintf выводит в файловый поток строку аргументов a1, a2, … в формате, указанном в строке format;

— в программу функция передает количество записанных аргументов;

— функция использует те же способы форматирования, что и функция printf().

Формат функции проверки достижения конца файла feof:

int feof (FILE *имя_потока) ;

Примечание:

— функция feof проверяет достижение конца файла;

— если конец файла не достигнут, то функция возвращает значение ‘0’, иначе — код 0xE0F.

Формат функции блочного ввода из файлового потока fread:

size_t fread (void *buf, size_t size, size_t N, FILE *имя_потока) ;

Примечание:

— функция fread считывает N блоков по size байт в область заданную указателем *buf из файлового потока;

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

— размер типа size_t указывает в соответствии со считываемым типом данных.

Формат функции блочного вывода в файловый поток fwrite:

size_t fwrite (const void *buf, size_t size, size_t N, FILE *имя_потока) ;

Примечание:

— функция fwrite записывает N блоков по size байт из области заданной указателем *buf в файловый поток;

— в программу функция возвращает количество записанных блоков;

— размер типа size_t указывает в соответствии с записываемым типом данных.

6.2.2. Файловый ввод и вывод с использованием классов языка С++

Формат объявления/открытия файлового потока:

fstream_class *имя_потока ( const char *имя_файла,

int режим_открытия ) ;

Здесь:

fstream_class — задает потоковый класс ввода/вывода:

fstream — потоковый класс для ввода/вывода в файл;

ifstream — потоковый класс для ввода из файла;

ofstream — потоковый класс для вывода в файл.

режим_открытия — задает режим открытия потока:

ios :: in — открыть для чтения;

ios :: out — открыть для записи;

ios :: ate — установить указатель на конец файла;

ios :: app — открыть для добавления данных в конец;

ios :: trunc — если файл существует, то удалить;

ios :: nocreate — если файл не существует, то выдать ошибку;

ios :: noreplace — если файл существует, то выдать ошибку;

ios :: binary — открыть в двоичном режиме.

Пример:

ifstream filein (“text.txt”, ios :: in) ;

ofstream fileout (“data.dat”, ios :: out | ios :: trunc | ios :: binary) ;

Примечания:

— в примере определяются два объекта filein и fileout входных потоков ifstream и выходных потоков ofstream;

— с указанными объектами можно работать также как со стандартными объектами cin и cout, т.е. использовать операции помещения в поток ‘<<’ и извлечения из потока ‘>>’, флаги форматирования, манипуляторы, методы, состояние потоков, использовать функции get и др.

Формат закрытия файлового потока:

имя_потока.close( ) ;

Примечания:

— функция-метод close() закрывает файловый поток;

— при выходе объекта из области видимости или завершении программы файловый поток закрывается автоматически.

Формат функции проверки достижения конца файла:

имя_потока.eof ( ) ;

Примечания:

— функция eof() класса ios проверяет достижение конца файла;

— если конец файла не достигнут, то функция возвращает значение ‘0’.

Произвольный доступ к записям файлов реализуется двумя методами:

имя_потока.seekg (смещение, ios :: аргумент) ;

имя_потока.seekp (смещение, ios :: аргумент) ;

Примечание:

— функция seekg предназначена для входных потоков;

— функция seekp предназначена для выходных потоков;

— обе функции производят смещение позиции чтения/записи на величину ‘смещение’ в байтах относительно позиции обозначенной аргументом ‘аргумент’:

beg — относительно начала файла;

cur — относительно текущей позиции чтения/записи;

end — относительно конца файла.

Получение текущего значения позиции в потоке ввода или вывода (в файле) реализуется следующим образом:

имя_потока.tellg ( ) ;

имя_потока.tellp ( ) ;

Примечания:

— функция tellg предназначена для входных потоков;

— функция tellp предназначена для выходных потоков.

Формат кода при неформатированном вводе из входного потока:

имя_потока.read (char *buffer, int N) ;

Примечание:

— функция read считывает N символов из входного потока и помещает считанные символы в переменную buffer.

Формат кода при неформатированном выводе в выходной поток:

имя_потока.write (const char *buffer, int N) ;

Примечание:

— функция write записывает N символов из переменной buffer в выходной поток.

Пример:

1)

#include<stdio.h> //0

int main()

{ FILE *filein, *fileout ; //1+3

filein=fopen(“file.txt”, “r”); //1

if (!filein) { printf (“Error: can’t open input file\n”) ; //2

return 1; } //2

else { printf (“Input file opened\n”); } //2

fileout=fopen(“file_.txt”, “w”) ; //3

if (!fileout) { printf(“Error: can’t open output file\n”) ; //4

return 1;} //4

else { printf (“Output file opened\n”) ; } //4

fseek(filein, 0, SEEK_END) ; //5

long lenfile=ftell(filein) ; //6

char *bufin=new char[lenfile+1] ; //7

rewind(filein); //8

fread(bufin, lenfile, 1, filein) ; //9

bufin[lenfile]= ‘\0’ ; //10

printf (“Filelength: %d byte. \n, lenfile”) ; //11

char *bufout=new char[lenfile] ; //12

long in=0, out=lenfile–1 ; //13

while (bufin[in]) //13

{ bufout[out]=bufin[in]; //13

in++; out– – ; //13

}

fwrite (bufout, lenfile, 1, fileout) ; //14

fclose (filein); printf(“Input file closed\n”) ; //15

fclose (fileout); printf(“Output file closed\n”) ; //16

delete []bufin; delete []bufout; //17

return 0;

}

2)

#include<fstream.h> //0, iostream.h подключается автоматически

int main()

{

ifstream filein(“file.txt”, ios :: in | ios :: nocreate) ; //1

if (!filein) { cout<<“Error: can’t open input file”<<endl; //2

return 1; } //2

else { cout<<“Input file opened”<<endl; } //2

ofstream fileout(“file_.txt”, ios :: out | ios :: trunc) ; //3

if (!fileout) { cout<<“Error: can’t open output file”<<endl; //4

return 1; } //4

else { cout<<“Output file opened”<<endl; } //4

filein.seekg(0, ios :: end); //5

long lenfile=filein.tellg(); //6

char *bufin=new char[lenfile+1] ; //7

filein.seekg(0, ios :: beg) ; //8

filein.read(bufin, lenfile) ; //9

bufin[lenfile]=‘\0’ ; //10

cout<<“File length: ”<<lenfile<<“ byte.”<<endl; //11

char *bufout=new char[lenfile] ; //12

long in=0, out=lenfile–1; //13

while (bufin[in]) //13

{

bufout[out]=bufin[in]; //13

in++; out– –; //13

}

fileout.write(bufout.lenfile) ; //14

filein.close(); cout<<“Input file closed”<<endl; //15

fileout.close(); cout<<“Output file closed”<<endl; //16

delete []bufin; delete []bufout; //17

return 0;

}

Результаты выполнения программ (пример 1 и 2), если содержимое файлов:

file.txt: 0123456789 test.

Информация в выходном файле: file_.txt: tset 9876543210

Информация на экране:

Input file opened

Output file opened

File length: 15 byte.

Input file closed

Output file closed

В примерах:

//0 — Подключение библиотек для работы с файлами в С или С++.

//1 — Объявление файлового потока, открывающего файл для чтения.

//2 — Проверка ошибок открытия файла для чтения.

//3 — Объявление файлового потока, открывающего файл для записи.

//4 — Проверка ошибок открытия файла для записи.

//5 — Установка счетчика позиции в конец читаемого файла для дальнейшего определения длины файла.

//6 — Определение длины файла lenfile.

//7 — Объявление вспомогательного массива размером [lenfile+1] для данных, считываемых из файла.

//8 — Установка счетчика позиции чтения из файла в начало файла.

//9 — Чтение всего файла одним блоком и запись данных во вспомогательный массив.

//10 — Запись символа ‘\0’ в конец строки (признак конца строки).

//11 — Вывод на экран информации о длине файла.

//12 — Создание вспомогательного массива выходных данных.

//13 — Обработка данных из массива входных данных и запись результата в массив выходных данных.

//14 — Запись данных из массива выходных данных в файл.

//15 — Закрытие потока (и файла), открытого для чтения.

//16 — Закрытие потока (и файла), открытого для записи.

//17 — Очистка динамической памяти от вспомогательных массивов входных и выходных данных.