Неформатированный ввод-вывод
В классе istream определены следующие функции. 1. istream& get(char* buffer,int size,char delimiter=’\n’); Эта функция извлекает символы из istream и копирует их в буфер. Операция прекращается при достижении конца файла, либо когда будет скопировано size символов, либо при обнаружении указанного разделителя. Сам разделитель не копируется и остается в streambuf. Последовательность прочитанных символов всегда завершается нулевым символом. 2. istream& read(char* buffer,int size); Не поддерживает разделителей, и считанные в буфер символы не завершаются нулевым символом. Количество считанных символов запоминается в istream::gcount_ (private). 3. istream& getline(char* buffer,int size, char delimiter=’\n’); Разделитель извлекается из потока, но в буфер не заносится. Это основная функция для извлечения строк из потока. Считанные символы завершаются нулевым символом. 4. istream& get(streambuf& s,char delimiter=’\n’); Копирует данные из istream в streambuf до тех пор, пока не обнаружит конец файла или символ-разделитель. Последний не извлекается из istream. В s нулевой символ не записывается. 5.istream get (char& С); Читает символ из istream в С. В случае ошибки С принимает значение 0XFF. 6.int get(); Извлекает из istream очередной символ. При обнаружении конца файла возвращает EOF. 7.int peek(); Возвращает очередной символ из istream, не извлекая его из istream. 8.int gcount(); Возвращает количество символов, считанных во время последней операции неформатированного ввода. 9.istream& putback(С) Если в области get объекта streambuf есть свободное пространство, то туда помещается символ С. 10.istream& ignore(int count=1,int target=EOF); Извлекает символ из istream, пока не произойдет следующего: - функция не извлечет count символов; - не будет обнаружен символ target; - не будет достигнуто конца файла.
В классе ostream определены следующие функции. 1.ostream& put(char C); Помещает в ostream символ С. 2.ostream& write(const char* buffer,int size); Записывает в ostream содержимое буфера. Символы копируются до тех пор, пока не возникнет ошибка или не будет скопировано size символов. Буфер записывается без форматирования. Обработка нулевых символов ничем не отличается от обработки других. Данная функция осуществляет передачу необработанных данных (бинарных или текстовых) в ostream. 3.ostream& flush(); Сбрасывает буфер streambuf. Следующие функции позволяют использовать прямой доступ. 1.istream& seekg(long p); Устанавливает указатель потока get (не путать с функцией) со смещением р от начала потока. 2.istream& seekg(long p,seek_dir point); Указывается начальная точка перемещения enum seek_dir{beg,curr,end} Положительное значение р перемещает указатель get вперед (к концу потока), отрицательное значение р – назад (к началу потока). 3.long tellg(); Возвращает текущее положение указателя get. 4.ostream& seekp(long p); Перемещает указатель put в streambuf на позицию р от начала буфера streambuf. 5.ostream& seekp(long p,seek_dir point); Указывается начальная точка перемещения. 6.long tellp(); Возвращает текущее положение указателя.
Пример 6.11.1. Использование istream с filebuf для чтения #include<fstream.h> void main() {char buffer[80]; filebuf dir_file; //присоединение файла к объекту filebuf if(!dir_file.open(“dir.txt”,ios::in)) {cout<<“Ошибка\n”; return;} //создание потока ввода с присоединенным файлом istream dir_stream(&dir_file); for(;;); {//считывание очередной строки текста dir_stream.getline(buffer,sizeof(buffer)); if(dir_stream.eof())break; //печать строки текста cout<<“\n”<<buffer; } Нет необходимости закрывать файл явно: деструктор для dir_file сделает это автоматически.
Пример 6.11.2. Чтение текстового файла #include<fstream.h> void main() {ifstream fin(“c:\\user\\my.txt”); if(!fin){cout<<“\nОшибка”; return;} while(fin) {char buffer[80]; fin.getline(buffer,sizeof(buffer)); cout<<“\n”<<buffer;} }
Пример 6.11.3.Чтение текстового файла в бинарном режиме #include<fstream.h>
void main() {ifstream fin(“имя”,ios::binary); if(!fiin){cout<<“\nОшибка”; return;} while(fin) {char c; fin.get(c); cout<<c;} } Выходной поток можно прочитать и с помощью операции >> Например, dir_stream >>buffer; Для копирования всего файла используется и более быстрый способ, который связан с применением istream::operator>>(streambuf*) Эта функция выполняет все сразу без необходимости использования цикла и проверки конца файла. Она копирует символы из istream в streambuf, начиная с текущей позиции потока. Копирование прекращается при достижении конца файла. Цикл for в нашем примере можно заменить одной строкой ввода dir_stream>>cout.rdbuf(); Выражение cout.rdbuf() возвращает указатель на streambuf, используемый стандартным потоком вывода. ofstream::filebuf* rdbuf(); Затем вызывается функция istream::operator>>(strstreambuf*), которая копирует символы потока в буфер до тех пор, пока не будет достигнут конец файла или не возникнут какие-либо ошибки. Пример 6.11.4. Запоминание текущего каталога в файле #include<fstream.h> #include<dir.h> void main() {char buffer[80]; filebuf dir_file; if(!dir_file.open(“dir.txt”,ios::out)){cout<<“Ошибка\n”; return;} //создание потока вывода с присоединенным файлом ostream dir_stream(&dir_file); //определение пути к текущему каталогу if(getcwd(buffer,sizeof(buffer))==0){cout<<“Ошибка\n”; return;} //сохранение пути dir_stream<<“\nДиректорий: ”<<buffer<<“\n\n”; //сохранение каталога в файле struct ffblk file_block; if(findfirst“*.*”,&fileblock,0)) {dir_stream<<“Ошибка доступа к каталогу\n”; return;} do dir_stream<< file_block.ff_name<<“\n”; while(!findnext(&file_block)); }
Пример 6.11.5. Запись в поток текстового файла #include<fstream.h> void main() {ifstream fin(“имя”); ofstream fout(“имя”); if(!fin){cout<<“\nОшибка”; return;} if(!fout){cout<<“\nОшибка”; return;} //копирование пяти строк файла fin int count=0; while(fin && fout){ char buffer[80];fout<<buffer<<“\n”; if(++count==5)break;} } В этих примерах используется следующая схема создания потока. 1. Создается объект класса filebuf. filebuf dir_file; 2. Объект filebuf связывается с устройством (в нашем примере с дисковым файлом, который открывается либо в режиме in, либо out). dir_file.open(“dir.txt”,ios::in); При успешном выполнении функции возвращает указатель на собственный объект класса, в противном случае – нуль. 3. Создается поток как объект класса istream или ostream и связывается с объектом типа filebuf. istream dir_stream(&dir_file);
Конструктор создает объект dir_strcom и связывает его с dir_file. Файловый ввод-вывод Потоки для работы с файлами создаются как объекты следующих классов: ofstream – запись в файл; ifstream – чтение из файла; fstream – чтение/запись. Для создания потоков имеются следующие конструкторы:
1) fstream(); создает поток, не присоединяя его ни к какому файлу. 2) fstream(int file_descriptor); создает поток и присоединяет его к уже открытому файлу. 3)fstream(int fd,char* buffer,int size); Этот конструктор получает буфер buffer размером size и использует его для создания внутреннего объекта filebuf. Поток присоединяется к уже открытому файлу. 4)fstream(const char* name,int mode,int p=filebuf::openprot); создает поток, присоединяет его к файлу с именем name, предварительно открыв файл, устанавливает для него режим mode и уровень защиты p. Если файл не существует, то он создается. Для m=ios::out, если файл существует, то его размер будет усечен до нуля. Флаги режима имеют следующие значения. enum ios::open_mode{ in=0X01, //для чтения out=0X02, //для записи ate=0X04, /*индекс потока помещен в конец файла. Чтение больше не допустимо, //выводные данные записываются в конец файла. При открытии файла //ищется конец файла. Далее можно указать seekp(k);*/ app=0X08, /*поток открыт для добавления данных в конец. Независимо от seekp будет писаться в конец */ trunc=0X10, //усечение существующего потока до нуля nocreate=0X20, /*команда открытия потока будет завершена неудачно, если файл не существует*/ noreplace=0X40, /*команда открытия потока будет завершена неудачно, если файл существует*/ binary=0X80, //поток открывается для двоичного обмена }; static const int filebuf::openprot указывает на тип защиты доступа к файлам. Система DOS предлагает ограниченный набор защитных механизмов, поэтому по умолчанию защита файлов установлена в(S_IREAD|S_IWRITE). Системы UNIX могут использовать openprot для предоставления определенным категориям пользователей прав на чтение, запись или выполнение файла. Если при создании потока он не присоединен к файлу, то присоединить существующий поток к файлу можно функцией. void open(const char* name,int mode,int p=filebuf::openprot); Функция void fstreambase::close(); сбрасывает буфер потока, отсоединяет поток от файла и закрывает файл. Эту функцию необходимо явно вызвать при изменении режима работы с потоком. Автоматически она вызывается только при завершении программы.
Пример 6.12.1. Запись в бинарные файлы #include<iostream.h> #include<fstream.h> struct Person{ char name[10]; int age; float salary;}; void main {//открытие файла ofstream fout(“person.dat”,ios::binary); //проверка на ошибки открытия if(!fout){cout<<“Ошибка\n”; return;} Person employee; int k=0; while(k<10 && fout) {cout<<“name=”; cin>> employee.name; cout<<“age=”; cin>> employee.age; cout<<“salary=”; cin>> employee.salary; fout.write((char*)&employee,sizeof(employee)); k++;} fout.seekp(0,ios::end); long size=fout.tellp(); cout<<“записано ”<<size<<“ байт\n”; } Пример 6.12.2. Чтение бинарного файла #include<iostream.h> #include<fstream.h> struct Person; void main() {ifstream fin(“person.dat”,ios::binary); if(!fin){cout<<“Ошибка\n”; return;} fin.seekg(0,ios::end); long size=fin.tellg(); cout<<“В файле ”<<size<<“ байт\n”; fin.seekg(0,ios::beg); Person employee; int k=0; fin.read((char*)&employee,sizeof(employee)); while(fin) {cout<<“name=”<<employee.name<<“ age=”<<employee.age <<“ salary=”<<employee.salary<<endl; k++; fin.read((char*)&employee,sizeof(employee));} cout<<“прочитано ”<<k<<“ записей\n”; } Пример 6.12.3. Запись в бинарный файл структуры перегруженной операцией << #include<fstream.h> struct Person; ofstream& operator<<(ofstream& out, Person& item) {out.write((char*)& item,sizeof(item));} void main() {ofstream fout(“person.dat”,ios::binary); if(!fout){…} int k=0; TPerson employee; while(k<10 && fout) {//сформировать employee fout<<employee; k++;} fout.seekp(0,ios::end); long size=fout.tellp(); cout<<“записано ”<<size<<“ байт\n”; }
Общая схема записи в файл 1)создать потоковый объект fstream f; 2)открыть для записи f.open(“имя”,ios::out|ios::binary); 3)выполнять в цикле запись из переменной в файл f.write((char*)&zap,sizeof(zap)); 4)закрыть файл f.close();
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|