Организация работы с файлами
В языке С++ для организации работы с файлами используются классы потоков ifstream (ввод), ofstream (вывод) и fstream (ввод и вывод) (рис. 7). Перечисленные классы являются производными от istream, ostream и iostream соответственно. Операции ввода-вывода выполняются так же, как и для других потоков, то есть компоненты-функции, операции и манипуляторы могут быть применены и к потокам файлов. Различие состоит в том, как создаются объекты и как они привязываются к требуемым файлам. В С++ файл открывается путем стыковки его с соответствующим потоком. Рассмотрим организацию связывания потока с некоторым файлом. Для этого используются конструкторы классов ifstream и ofsream: ofstream(const char* Name, int nMode= ios::out, int nPot= filebuf::openprot); ifstream(const char* Name, int nMode= ios::in, int nPot= filebuf::openprot); Первый аргумент определяет имя файла (единственный обязательный параметр). Второй аргумент задает режим для открытия файла и представляет битовое ИЛИ (|) величин: ios::app при записи данные добавляются в конец файла, даже если текущая позиция была перед этим изменена функцией ostream::seekp; ios::ate указатель перемещается в конец файла. Данные записываются в текущую позицию (произвольное место) файла; ios::in поток создается для ввода, если файл уже существует, то он сохраняется; ios::out поток создается для вывода (по умолчанию для всех ofstream объектов), если файл уже существует, то он уничтожается; ios::trunc если файл уже существует, его содержимое уничтожается (длина равна нулю). Этот режим действует по умолчанию, если ios::out установлен, а ios::ate, ios::app или ios:in не установлены; ios::nocreate если файл не существует, функциональные сбои; ios::noreplace если файл уже существует, функциональные сбои; ios::binary ввод-вывод будет выполняться в двоичном виде (по умолчанию текстовой режим).
Возможны следующие комбинации перечисленных выше величин: ios::out | ios::trunc удаляется существующий файл и (или) создается для записи; ios::out | ios::a pp открывается существующий файл для дозаписи в конец файла.; ios::in | ios::out открывается существующий файл для чтения и записи:; ios::in | ios::out | ios::trunc существующий файл удаляется и (или) создается для для чтения и записи; ios::in | ios::out | ios::app открывается существующий файл для чтения и дозаписи в конец файла. Третий аргумент – данное класса filebuf, используется для установки атрибутов доступа к открываемому файлу. Возможные значения nProt: filebuf::sh_compat совместно используют режим; filebuf::sh_none режим Exclusive: никакое совместное использование; filebuf::sh_read совместно использующее чтение; filebuf::sh_write совместно использующее запись. Для комбинации атрибутов filebuf::sh_read и filebuf::sh_write используется операция логическое ИЛИ (||). В отличие от рассмотренного подхода можно создать поток, используя конструктор без аргументов. Позже вызвать функцию open, имеющую те же аргументы, что и конструктор, при этом второй аргумент не может быть задан по умолчанию: void open(const char* name, int mode, int prot=fileout::openprot); Только после того как поток создан и соединен с некоторым файлом (используя либо конструктор с параметрами, либо функцию open), можно выполнять ввод информации в файл или вывод из файла. #include "iostream.h" #include "fstream.h" #include "string.h" Class string { char *st; int size; public: string(char *ST,int SIZE): size(SIZE) { st=new char[size]; strcpy(st,ST); } ~string() {delete [] st;} string(const string &s) // копирующий конструктор необходим, так как { st=new char[s.size]; // при перегрузке << в функцию operator переда- strcpy(st,s.st); // ется объект, содержащий указатель на строку, а } // в конце вызовется деструктор для объекта obj friend ostream &operator<<(ostream &,const string); friend istream &operator>>(istream &,string &); }; ostream &operator<<(ostream &out,const string obj) { out << obj.st << endl; return out;
} istream &operator>>(istream &in,string &obj) { in >> obj.st; return in; } main() { string s("asgg",10),ss("aaa",10); int state; ofstream out("file"); if (!out) { cout<<"ошибка открытия файла"<<endl; return 1; // или exit(1) } out<<"123"<<endl; out<<s<<ss<<endl; // запись в файл ifstream in("file"); while(in >> ss) // чтение из файла {cout<<ss<<endl;} in.close(); out.close(); return 0; } В приведенном примере в классе содержится копирующий конструктор, так как в функцию operator передается объект obj, компонентой которого является строка. В инструкции cout <<s<<ss копирующий конструктор вызывается вначале для объекта ss, затем для s, после этого выполняется перегрузка в порядке, показанном ранее. При завершении каждой из функций operator<< (вначале для s, затем для ss) будет вызван деструктор. В операторе if (!out) вызывается (как и ранее для потоков) функция ios::operator! для определения, успешно ли открылся файл. Условие в заголовке оператора while автоматически вызывает функцию класса ios перегрузки операции void *: operator void *() const { if(state&(badbit|failbit)) return 0; return (void *)this; } то есть выполняется проверка; если для потока устанавливается failbit или badbit, то возвращается 0.
Воспользуйтесь поиском по сайту: ©2015 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|