В консольном режимесуществует понятие стандартных файловых потоков: stdin - ввод (по умолчанию - клавиатура), stdout - вывод (по умолчанию - консоль), stderr- вывод сообщений об ошибках (по умолчанию - консоль).
Эти потоки имеют тип FILE * , и их удобство в том, что их можно перенаправлять функцией freopen() , например:
freopen("results.txt", "w", stdout);
Теперь все результаты работы программы будут выводиться в файл results.txt так же, как они выводились бы на экран консоли.
Замечание. В случае перенаправления stdin не рекомендуется при вводе пользоватьсяfflush(), т.к. с файлом она работает иначе, чем с клавиатурой, из-за различной буферизации их в компьютере (см. также тему «Функции ввода-вывода»). Вместо нее надо использовать другие средства. Например, если после scanf() функция gets() вводит пустую строку, можно дважды вызывать gets().
При чтении-записи бинарных (двоичных) файлов удобнее всего пользоваться функциями, выполняющими блоковый ввод-вывод: fread() и fwrite().
Пример: Сохранить, а затем прочесть из файла значения целых переменных i и j .
Рассмотрим некоторые функции, которые могут пригодиться для работы с файлами (они работают с любыми файлами, но чаще применяются к бинарным):
int fileno(FILE *f)
– возвращает значение дескриптора файла f - fd (число, определяющее номер файла);
long filelength(int fd)
– возвращает длину в байтах файла, имеющего номер (дескриптор) fd; Часто поэтому применяется вместе с fileno();
int chsize(int fd, long pos)
– выполняет изменение размера файла, имеющего номер fd, конец файла устанавливается после байта с номером pos;
intfseek(FILE *f, long size,
int kod)
– выполняет смещение указателя позиции в файле f на size байт в направлении признака kod:
0 - от начала файла;
1 - от текущей позиции указателя;
2 - от конца файла.
Заметим, что при kod>0 может быть size<0.
long ftell(FILE *f)
– возвращает значение указателя позиции в файле (-1 – ошибка);
intfgetpos(FILE *f,
long *pos)
– определяет значение текущей позиции pos файла f, возвращает 0 при успешном завершении.
Функция fseek может многократно ускорять и упрощать работу с файлами, т.к. она позволяет начать чтение/запись в файле сразу с требуемого места. Подобный способ работы называется прямым доступом к файлу, в отличие от обычного, последовательного доступа, когда информация читается последовательно, от начала к концу. Прямой доступ широко применяется для баз данных. Однако прямой доступ применяется в основном для бинарных файлов (в текстовых файлах трудно вычислить значение нужной позиции в байтах, т.к. разные строки могут иметь разную длину).
При расчете смещения для fseek может пригодиться операция sizeof.
Замечание. Из-за буферизации (см. выше) непосредственно после операции записи нельзя выполнять чтение, и наоборот (не считая случая, когда при чтении достигнут конец файла, что гарантирует исчерпание буфера). Либо файл должен быть переоткрыт заново, либо указатель позиции должен быть установлен в заданное место с помощью fseek.