Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Тема 12. Файловый ввод-выводСодержание книги
Поиск на нашем сайте
Файловый и консольный ввод-вывод очень близко связаны. Фактически файловый ввод-вывод поддерживается той же иерархией классов, что и консольный ввод-вывод. Когда программа начинает работу, четыре потока инициализируются автоматически и связываются с соответствующими им стандартными файлами (устройствами) – это cin, cout, cerr и clog. Если нужно инициализировать еще и другие потоки и связать их с некоторыми файлами, то сделать это следует явно. Любой инициализируемый файловый поток может быть лиьо потоком ввода, либо потоком вывода, либо потоком ввода-вывода. Поток ввода – это всегда объект класса istream, порожденного из класса istream. Поток вывода – это всегда объект класса ofstream, порожденного из класса ostream. Поток ввода-вывода – это всегда объект класса fstream, порожденного из класса iostream. В каждом из этих классов имеются конструкторы, выполняющие работу по связыванию объекта класса с соответствующим файлом. Классы для работы с файлами наследуют от потоковых классов перегруженные операции “<<” и “>>”, флаги и методы форматирования, манипуляторы, средства проверки состояния потоков и т.п. Использование файлов в программе предполагает следующие действия: 1. Создание потока. 2. Открытие потока и связывание его с файлом. 3. Обмен с потоком (ввод-вывод). 4. Закрытие файла. 5. Уничтожение потока. Конструкторы без параметров создают объект не связывая его с файлом. Конструкторы с параметрами создают объект, открывают файл с указанным именем в заданном режиме и связывают файл с объектом. Если установленное по умолчанию значение режима открытия файла не устраивает программиста, то можно указать другое, составив его из битовых масок, определенных в классе ios, с помощью битовой операции “|”. После создания потока, одним из способом связать его с файлом является функция open( ), которая является членом всех файловых потоковых классов. Если выполнение функции open() завершилось с ошибкой, в булевом выражении поток будет равен значению false. Для закрытия файла используется функция close() не имеющая параметров и возвращаемого значения. Рассмотрим один практически значимый пример иллюстрирующий такие важные аспекты программирования, как: потоковый ввод-вывод, использование шаблонов классов при передаче параметров из конструктора производного класса в конструктор базового класса, работа с двумерным массивом, размещаемым в динамической памяти. В силу ограниченности объема лекции в приводимой программе рассматриваются только характерные особенности отмеченных аспектов, а все виды контроля опущены. // определение класса IOFile для открытия/закрытия файлов class IOFile: public fstream { public: void open_f(char *filename, int mode) { open (filename, mode); } void close_f (char *filename) { close ();} };
// шаблон базовых классов для работы с матрицами
template <class T> // T – обобщенный тип элемента class Matrix_B // Класс – «Матрица» - базовый класс { protected: T ** array; // указатель на массив указателей на строки int rows, columns; public: Matrix_B (int n, int m); // конструктор Matrix_B (const Matrix_B<T>©); // конструктор копирования ~Matrix_B (void); // деструктор void ReadMatrix (char *fp); // чтение элементов матрицы из файла };
template<class T>Matrix_B<T>:: Matrix_B (int n, int m) { array= new T *[n]; // динамическое выделение памяти под матрицу for (int i=0; i<n; i++) array[i]= new T [m]; for (i=0; i<n; i++) for (int j=0; j<m; j++) array[i][j]=(T) 0; rows=n; columns=m; return; }
// конструктор копирования template<class T>Matrix_B<T>::Matrix_B (const Matrix_B<T> & copy) { array= new T *[copy.rows]; for (int i=0; i<copy.rows; i++) array[i]= new T [copy.columns]; for (i=0; i<copy.rows; i++) for (int j =0; j<copy.columns; j++) array[i][j]=copy.array[i][j]; rows=copy.rows; columns=copy.columns; }
template<class T>Matrix_B<T>::~Matrix_B (void) // деструктор { for (int i=0; i<rows; i++) delete [] array[i]; delete [] array; }
// чтение элементов матрицы из заданного файла template<class T> void Matrix_B<T>::ReadMatrix (char *fp) { IOFile fin; fin.open_f (fp, ios::in); for (int i=0; i<rows; i++) for (int j =0; j<columns; j++) fin>>array[i][j]; fin.close_f(fp); return; }
// Определение шаблона производных классов для работы с матрицами template <class T> class Matrix_D: public Matrix_B<T> { public: Matrix_D (int nrow, int ncol); void PrintMatrix (IOFile &); // Печать матрицы // Перегрузка операций сложения, присваивания и индексации Matrix_ D<T> operator + (const Matrix_D<T>&); Matrix_ D<T>& operator =(const Matrix_D<T>&); T *& operator [] (int index); // Конструктор производного класса template <class T> Matrix_D <T>::Matrix_D (int nrow, int ncol): Matrix_B<T>(nrow,ncol) {}
// Перегрузка операции сложения template<class T> Matrix_D<T> Matrix_D<T>:: operator + (const Matrix_D<T>&ref) { Matrix_D<T> result(rows, columns); // Создание пустого объекта for (int i=0; i<rows; i++) for (int j=0; j<columns; j++) result.array[i][j]=array[i][j]+ref.array[i][j]; return result; }
// Перегрузка операции присваивания template<class T> Matrix_D<T>& Matrix_D<T>:: operator =(const Matrix_D<T>&ref) { for (int i=0; i<rows; i++) for (int j=0; j<columns; j++) array[i][j]=ref.array[i][j]; rows=ref.rows; columns=ref.columns; return * this; }
// Печать матрицы template<class T> void Matrix_D<T>::PrintMatrix (IOFile & fout) { for (int i=0; i<rows; i++) { for (int j=0; j<columns; j++) fout << array[i][j]<<’ ‘; fout <<endl; } return; }
// Перегрузка операции индексации template <class T> T *& Matrix_D<T>:: operator [] (int index) { return array[index]; }
// Тестирование программы
int main (void) // main возвращает 0 при успехе { IOFile fout; // объект для записи в файл “matrix.out” fout.open_f (“matrix.out”, ios::out); // Создаем объекты-массивы, заполняем их из файла и печатаем Matrix_D < int > a1(2,2), a2(2,2), a3(2,2); a1.ReadMatrix (“matrix.in”); a2.ReadMatrix(“matrix.in”); a3.ReadMatrix(“matrix.in”); fout<<”\n a1: “<< endl; a1.PrintMatrix(fout); fout<<”\n a2: “<< endl; a2.PrintMatrix(fout); fout<<”\n a3: “<< end l; a3.PrintMatrix(fout);
// Тестирование перегруженной операции [] fout<<”\n Тестирование перегруженной операции []:”<<”\n int k=a1[1][1];”<< endl; int k=a1[1][1]; fout<<”\n k=”<<k<< endl;
// Тестирование элементарных выражений fout<<”\n Тестирование элементарных выражений \n”<<”a3=a1+a2;”<< endl; a3=a1+a2; fout<<”\n a3=”<< endl; a3.PrintMatrix(fout); // Закрытие файла вывода fout.close_f (“matrix.out”); return 0; }
Основная литература – 5 [Гл. 11, 431–444], 6 [Гл. 5, 135–158], 7 [Гл. 9, 243–275], 8 [Гл.9, 275–302].
Вопросы контроля 1. Зачем создавать потоки ввода-вывода, если отлично работают семейства функций scanf()-fscanf(), printf()- fprintf()-sprinf()? 2. Когда следует применять метод ignore ()? 3. Какая ширина поля вывода принимается по умолчанию при выводе целых чисел? 4. Какое значение возвращает перегруженный оператор вывода? 5. Что обеспечивает элементарный режим открытия ios::ate?
|
||
Последнее изменение этой страницы: 2016-12-13; просмотров: 169; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.221.93.167 (0.005 с.) |