Создание указателя на предопределенный тип FILE.
Для работы с файлом в языке C++ необходима ссылка на файл. Для определения такой ссылки существует тип FILE, определенный в заголовочном файле stdio.h. Обычно он представляет собой совокупность структур, содержащую все необходимые параметры для управления файлами, например: текущий счетчик байтов, базовый адрес буфера ввода-вывода, номер файла реализации потока, адреса буферов, указатели позиций потока, маркеры ошибок потока и т.д.
FILE * указатель;
Например:
#include<stdio.h>..............FILE *fp;2) Открытие
При открытии файла (потока) в программу возвращается указатель на поток (файловый указатель), являющийся указателем на объект структурного типа FILE. Этот указатель идентифицирует поток во всех последующих операциях.
В момент их открытия следует задать режим доступа, чтобы определить, к какому файлу осуществляется доступ: текстовому или бинарному (двоичному), а также способ доступа: чтение или запись. Функция открытия имеет формат:
FILE fopen (const char* имя_файла,const char* режим_открытия_файла);
или проще
указатель= fopen (“имя_файла”, “режим_доступа”);
При успешном открытии файла функция возвращает указатель на предопределенную структуру типа FILE, содержащую всю необходимую для работы с потоком информацию, или NULL в противном случае. Имя открываемого файла должно быть заключено в кавычки и может содержать путь (перечисление диска и вложенных папок, где расположен файл).
Режим открытия файла может быть одним из представленных в таблице 2.
Таблица 2. Режимы открытия файла
mode | режим открытия файла |
r | Файл открывается для чтения. При успешном открытии файла указатель файла (считывающая головка) устанавливается в 0. Если файл с заданной спецификацией не существовал, функция fopen возвращает NULL. |
w | Файл открывается для записи. Если файл не существовал он создаётся в заданном директории с именем filename. Если файл существовал указатель файла (считывающая головка) устанавливается в 0. При необходимости сохранения содержимого данного файла необходимо выполнить принудительное позиционирование считывающей головки. Немедленное закрытие файла, после его открытия, приводит к переопределению длины файла, соответствующее текущему положению считывающей головки. |
a | Файл открывается для пополнения. После открытия файла указатель файла устанавливается на позицию конца файла. В результате при записи в файл сохраняется содержимое файла. |
r+ | Файл открывается для обновления (чтения и записи). После открытия файла указатель файла устанавливается на позицию 0. Однако немедленное закрытие файла не приводит к его усечению. |
w+ | Файл открывается для обновления (чтения и записи). Если файл не существовал он создаётся в заданном директории с именем filename. После открытия файла указатель файла устанавливается на позицию 0, а немедленное закрытие файла приводит к его усечению. |
a+ | Файл открывается для обновления (чтения и записи). После открытия файла указатель файла устанавливается на позицию EOF. Закрытие файла не приводит к его усечению. |
b | Файл открывается двоичном режиме. Специфицируется двоичный файл путём добавления символа b после символов r,w,a,r+,w+,a+. Например: "r+b","w+b". |
t | Файл открывается текстовом режиме. Специфицируется текстовый файл путём добавления символа t после символов r,w,a,r+,w+,a+. Например: "r+t","wt". |
Режим открытия может также может содержать символы:
t – текстовый режим;
b – двоичный режим.
Например:
"r+b" или "rb" – двоичный (бинарный) режим;
"r+t" или "rt" – текстовый режим.
По умолчанию файл открывается в текстовом режиме, при котором комбинация “возврат каретки” и “перевод строки” при вводе преобразуются в одиночный символ перевода строки (при выводе выполняется обратное преобразование). В двоичном режиме эти преобразования не выполняются.
Пример:
FILE *f = fopen (“d:\\cpp\\data”, “rb+”);
Указатель f используется в дальнейших операторах с потоком. Его передают функциям ввода/вывода в качестве параметра.
или
FILE *ft; // объявили указатель на файловый поток
ft = fopen(“inp_f.txt”, “r”); // открыли файл inp_f.txt
При попытке открыть существующий файл можно допустить ошибку в его имени или в указании пути к нужному файлу. Это вызывает ошибку исполнения программы. Следует предвидеть подобные ситуации и проводить проверку возможности открытия файла. Такую проверку осуществить довольно легко, так как функция fopen() возвращает значение указателя в случае успешного его открытия и значение NULL, если доступ к файлу невозможен. Поэтому достаточно написать
FILE *ft; // объявили указатель на файловый поток
if (ft = fopen(“inp_f.txt”, “r”)== NULL) // проверка открытия файла
{ <сообщение об ошибке> }
else { <обработка файла> }
При открытии файла могут возникать следующие ошибки:
· файл, связанный с потоком не найден (при чтении из файла);
· диск заполнен (при записи);
· диск защищен от записи (при записи) и т. п.
В этих случаях указатель на поток приобретет значение NULL (0). Указатель на поток, отличный от аварийного, не бывает равен NULL.
Для вывода сообщения об ошибке при открытии файла используется стандартная библиотечная функция из файла <stdio.h>:
void perror (const char*s);Функция perror() выводит строку символов, адресуемую указателем s, за которой размещаются: двоеточие, пробел и сообщение об ошибке. Содержимое и формат сообщения определяются реализацией системы программирования.
Пример 1. Обнаружение и вывод ошибки при открытии файла.
#include "stdafx.h"#include <iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){ FILE *fp; if ((fp=fopen("t.txt", "r"))==NULL) // выводит строку символов с сообщением об ошибке perror("ошибка при открытии файла"); system("pause"); return 0;}on_load_lecture();
При открытии потока с ним связывается область памяти, называемая буфером. Буферизация позволяет более быстро и эффективно обмениваться информацией с внешними устройствами. С помощью функций setbuf()и setvbuf() можно управлять размерами и наличием буферов.
3) Обработка (считывание блока данных из потока в оперативную память, запись блока данных из оперативной памяти в поток, считывание определенной записи данных из потока, занесение определенной записи данных в поток);
4) Закрытие файла.
Закрытие файла приводит к разрушению внутренней переменной, созданной по шаблону file. При этом, содержимое буфера переносится на диск и выполняется DOS - функция закрытия файла: происходит обновление директория - записывается новый размер файла и изменяется дата и время создания файла.
Файл закрывается:
- при завершении программы;
- явным образом с помощью функции fclose():
int fclose ( FILE * );
Возвращает 0 при успешном закрытии файла и -1 в противном случае.
Перед закрытием потока информация из связанных с ним буферов выгружается на диск. Рекомендуется всегда явным образом закрывать потоки, открытые для записи, чтобы избежать потери данных. Это является хорошим тоном в программировании.
Закрытие всех открытых файлов:
Fcloseall(void);
Открытый файл можно открыть повторно (например, для изменения режима работы с ним) только после того, как файл будет закрыт с помощью функции fclose().