- •Введение. Принципы объектно-ориентированного программирования
- •Глава 1. Классы и объекты
- •1.1. Операция разрешения области видимости ::
- •1.2. Перечислимый тип
- •1.3. Модификатор const
- •1.4. Новый тип данных – ссылка &
- •Inline определение_функции
- •2. Определение класса. Сокрытие информации.
- •3. Объект.
- •4. Конструкторы и деструкторы
- •4.1.Назначение конструктора
- •4.2. Конструктор копирования
- •X::X(X&); // где X – имя класса
- •4.3. Деструктор
- •5. Неявный указатель this
- •6. Перегрузка операций
- •7. Примеры перегрузки некоторых операций
- •7.1. Перегрузка операции [ ]
- •7.2. Перегрузка операции ()
- •7.6. Перегрузка операции (тип)
- •8. Дружественность
- •Istream
- •10. Массивы объектов.
- •11. Функции- и классы-шаблоны
- •11.1 Функции-шаблоны (родовые функции)
- •11.2 Классы-шаблоны
- •12. Член-данные класса – объекты другого класса: агрегированные классы.
- •Глава 2. Наследование. Полиморфизм
- •1. Базовый и порожденный классы
- •2. Конструкторы порожденного класса
- •3. Стандартные преобразования при наследовании
- •4. Множественное наследование. Виртуальный базовый класс
- •4.1. Прямые базовые классы
- •4.2. Виртуальный базовый класс
- •5. Полиморфизм, раннее и позднее связывание, виртуальные функции
- •5.1 Раннее (статическое) и позднее (динамическое) связывание
- •5.2. Определение виртуальной функции
- •5.3. Чистая виртуальная функция и абстрактный класс
- •5.4. Правила определения виртуальных функций
- •5.5. Механизм позднего связывания
- •6. Библиотека fstream – работа с файлами
- •Глава 3. Библиотека стандартных шаблонов (бсш). Контейнеры
- •1. Контейнер. Структура бсш.
- •2. Контейнер Vector – динамический массив
- •Контейнер list – список
- •4. Контейнер Set – множество
- •Содержание
- •Глава 1. Классы и объекты
- •Глава 2. Наследование. Полиморфизм
- •Глава 3. Библиотека стандартных шаблонов (бсш). Контейнеры
6. Библиотека fstream – работа с файлами
Рассмотренные в главе 1 п.9 классы потокового ввода istream и вывода ostream входят в иерархию классов, показанную на рисунке ниже.
В библиотеке fstream имеется 3 класса для работы с файлами:
ifstream – потоковый ввод из файла, данные только последовательно читаются, для чтения можно использовать операцию >>;
ofstream – потоковый вывод в файл, данные только последовательно записываются, для вывода можно использовать операцию <<;
fstream – потоковый ввод-вывод в файл, данные и читаются, и записываются в конец файла, используются операции >>, << соответственно.
В каждом из этих классов имеются конструкторы с аргументом char * для того, чтобы связать поток с конкретным файлом и разрешить работу с ним. Кроме конструктора связать файл с потоком можно функцией класса open() – открыть файл. Она перегружена в любом из этих классов. Функция close() закрывает файлы: формирует признак конца файла EOF (End Of File) для выходных файлов и запрещает потоку работать с ними.
Рассмотрим на примере работу с файлами.
Пример. Пусть имеется файл целых чисел с именем “f1.dat”. Читая числа из файла, положительные перепишем в файл с именем “f2.dat”.
#include <fstream.h>
void main( )
{ifstream f(“f1.dat”); // конструктор с аргументом char * связывает файл с именем “f1.dat” с потоком ввода f
// или можно так: ifstream f; f.open(“f1.dat”);
ofstream g(“f2.dat”); // конструктор с аргументом char * связывает поток вывода g с файлом “f2.dat”.
// Если такой файл уже был, то он будет разрушен.
int x;
while (f >> x) // прочитать число из файла “f1.dat” и записать его в x. Если все числа прочитаны,
// т.е. файл закончился, то операция возвращает 0 (NULL)
if (x > 0) g << x << ’ ‘; // записать число x > 0 в файл “f2.dat”
f.close( ); g.close( ); // файлы закрыты, больше их использовать нельзя!
}
Проверку на конец файла можно делать и специальной функцией-предикатом eof(). Она возвращает истину, если файл закончился, и ложь, если нет. Используя функцию eof(), цикл можно организовать таким образом:
while (!f.eof( )) { ... }
По умолчанию файлы считаются текстовыми, т.е. если это числа, то они преобразуются в символьный вид при выводе и из символьного в числовой при вводе.
Конструкторы этих классов, а также функция open(), могут иметь дополнительный второй аргумент, конкретизирующий способ работы с файлом (атрибут). Атрибут задается как перечислимый тип (enum), определенный в базовом классе ios.
Перечислим несколько часто используемых атрибутов:
ios::in – открыть файл для ввода (для объектов ifstream по умолчанию ),
ios::out – открыть файл для вывода (для объектов ofstream по умолчанию ),
ios::app – открыть файл для записи в конец файла, если файла еще нет – создается,
ios::binary – открыть файл как двоичный, то есть не выполняется преобразование в символьную форму (удобен для вывода структур).
Если для файла надо задать несколько атрибутов, то они связываются операцией логическое «или» ( | ), которая трактуется как объединение атрибутов.
Например, открыть двоичный файл для дополнения можно так:
ofstream f(“ff.dat”, ios::app | ios::binary);
Приведем еще примеры работы с файлами:
void main( )
{int i;
ofstream f; f.open("f4.dat"); // для дополнения ios::app); или ofstream f("f4.dat");
for (i = 0; i < 20; i++)
f << random(100) << ' ';
f.close( );
ofstream g[3] = {"g1.dat", "g2.dat", "g3.dat"}; // 3 файла для вывода
g[0] << 555 << ' ';
g[1] << "666 + 777";
g[2] << 45.78;
for(i = 0; i < 3; i++)
g[i].close( ); // закрыли
ofstream *t = new ofstream [2]; // массив из 2-х потоковых файлов вывода, но связи с реальным файлом нет
t[0].open("ah.dat"); // связать с
t[1].open("oh.dat"); // конкретными файлами
t[0] << "Ах!"; //запись строки в файл
t[1] << "Ох!";
t[0].close( ); t[1].close( ); // закрыли файлы
ifstream r("ah.dat"); // открыли поток r для чтения
char s[15];
f.open("plus.txt"); // открыли для записи выходной поток f, используется повторно
r >> s; f << s; // чтение строки до ' ' из потока r и запись в поток f
// r.getline(s,30); //чтение всей строки
cout << s;
r.close( ); // закрыли работу с файлом "ah.dat"
r.open("oh.dat"); // открыли повторно входной поток r для чтения из файла "oh.dat"
r >> s; f << s; // прочитали строку из файла "oh.dat" и записали ее в файл "plus.txt"
f.close( ); r.close( ); // закрыли оба файла
ifstream *ff = new ifstream("plus.txt"); // открыли поток ввода в динамической памяти для
// чтения из файла “plus.txt”
(*ff) >> s; // прочитали из него строку
cout << "s = " << s; // вывели на экран
ff –> close( ); // закрыли
fstream z("plus.txt", ios::in | ios::out);// открыли поток ввода-вывода
z >> s; cout << s; // прочитали из него строку
z << "Ух!"; // записали в конец его новую строку
z.close( ); // закрыли файл “plus.txt”
z.open("plus.txt", ios::in); // и открыли его только для чтения
z >> s; // прочитали строку
cout << endl << s; // и вывели на экран
z.close( ); // закрыли
delete [t]; delete ff;
}
