Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции за I семестр конспект Гуревича для C++ B....doc
Скачиваний:
11
Добавлен:
21.11.2018
Размер:
1.3 Mб
Скачать

Int fflush(file *stream);

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

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

Для работы с текстовыми файлами удобнее всего пользоваться функциями fprintf(), fscanf(), fgets() и fputs().

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

Рассмотрим пример создания текстового файла:

#include<stdio.h>

void main(void) {

FILE *f1;

int a=2, b=3;

If(!(f1=fopen(“d:\\work\\f_rez.txt”,”w+t”)))

{ // Эапись (!f1) равносильна (f1==NULL)

puts(“Файл не создан!”);

return;

}

fprintf(f1,” Файл результатов \n”);

fprintf(f1,” %d плюс %d = %d\n”,a,b,a+b);

fclose(f1);

}

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

16.6. Перенаправление стандартного ввода-вывода

В консольном режиме существует понятие стандартных файловых потоков: stdin - ввод (по умолчанию - клавиатура), stdout - вывод (по умолчанию - консоль), stderr - вывод сообщений об ошибках (по умолчанию - консоль).

Эти потоки имеют тип FILE * , и их удобство в том, что их можно перенаправлять функцией freopen() , например:

freopen("results.txt", "w", stdout);

Теперь все результаты работы программы будут выводиться в файл results.txt так же, как они выводились бы на экран консоли.

Замечание. В случае перенаправления stdin не рекомендуется при вводе пользоваться fflush(), т.к. с файлом она работает иначе, чем с клавиатурой, из-за различной буферизации их в компьютере (см. также тему «Функции ввода-вывода»). Вместо нее надо использовать другие средства. Например, если после scanf() функция gets() вводит пустую строку, можно дважды вызывать gets().

16.7. Бинарные файлы

При чтении-записи бинарных (двоичных) файлов удобнее всего пользоваться функциями, выполняющи­ми блоковый ввод-вывод: fread() и fwrite().

Пример: Сохранить, а затем прочесть из файла значения целых переменных i и j .

int i,j;

void __fastcall TForm1::Button1Click(TObject *Sender)

{

FILE *f=fopen("my.dat", "wb");

fwrite(&i, sizeof(int), 1, f);

fwrite(&j, sizeof(int), 1, f);

fclose(f);

}

//--------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

FILE *g=fopen("my.dat", "rb");

fread(&i, sizeof(int), 1, g);

fread(&j, sizeof(int), 1, g);

fclose(g);

}

16.8. Дополнительные полезные функции

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

int fileno(FILE *f)

– возвращает значение дескриптора файла f - fd (число, определяющее номер файла);

long filelength(int fd)

– возвращает длину в байтах файла, имеющего номер (дескриптор) fd; Часто поэтому применяется вместе с fileno();

int chsize(int fd, long pos)

– выполняет изменение размера файла, имеющего номер fd, конец файла устанавливается после байта с номером pos;

int fseek(FILE *f, long size,

int kod)

– выполняет смещение указателя позиции в файле f на size байт в направлении признака kod:

0 - от начала файла;

1 - от текущей позиции указателя;

  1. - от конца файла.

Заметим, что при kod>0 может быть size<0.

long ftell(FILE *f)

– возвращает значение указателя позиции в файле (-1 – ошибка);

int fgetpos(FILE *f,

long *pos)

– определяет значение текущей позиции pos файла f, возвращает 0 при успешном завершении.

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

При расчете смещения для fseek может пригодиться операция sizeof.

Замечание. Из-за буферизации (см. выше) непосредственно после операции записи нельзя выполнять чтение, и наоборот (не считая случая, когда при чтении достигнут конец файла, что гарантирует исчерпание буфера). Либо файл должен быть переоткрыт заново, либо указатель позиции должен быть установлен в заданное место с помощью fseek.