![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Краткие теоретические сведения. Обычно на практике большие объемы данных хранятся в файлах
Обычно на практике большие объемы данных хранятся в файлах. Поэтому дополним наш шаблон методами, позволяющими вводить и выводить массивы в файл. В Си++ можно работать как с текстовыми файлами, информация в которых представлена в кодах ASCII, так и с бинарными, в которых информация хранится в бинарных кодах. Для работы с текстовыми файлами используются операторы < < и > >, только работают они не со стандартными потоками, а с потоками связанными с файлом. template < class typeArray> void tArray < typeArray>:: outputTFile(char* filename){ // функция вывода в текстовый файл ofstream out(filename); //инициализируем поток ввода /*если не удалось открыть файл, выводим сообщение и завершаем работу*/ if (! out){cout< < " Cann't open file " < < filename< < " for output! "; exit; } for (int i=0; i< n; i++){out< < B[i]; }//вывод элементов в файл out.close(); //закрываем поток } template < class typeArray> void tArray < typeArray>:: inputTFile(char* filename){ //функция ввода из текстового файла ifstream in(filename); if (! in){cout< < " Cann't open file " < < filename< < " for input! "; exit; } for (int i=0; i< n; i++){in> > B[i]; } in.close(); } void main(){ tArray < int> C(3); C.input(); //ввод с клавиатуры C.outputTFile(); //вывод в текстовый файл C.inputTFile(); //ввод из текстового файла C.output(); //вывод на экран } Открытие файлов осуществляется с помощью конструкторов классов ifstream, ofstream и fstream, которые в качестве параметров получают имя файла и режим доступа (может отсутствовать). Для работы с файлами необходимо подключить библиотеку < fstream.h>. Для того чтобы описанные выше шаблонные функции можно было использовать с массивами объектов класса sportsmen, необходимо этот класс модифицировать. Для это добавим в него две дружественные функции, переопределяющие операторы > > и < < для потоков связанных с файлом (ifstream и ofstream). ofstream & operator< < (ofstream & stream, sportsmen ob){ stream< < ob.id< < " " < < ob.surname< < " " < < ob.result< < endl; return stream; }; ifstream & operator> > (ifstream & stream, sportsmen & ob){ stream> > ob.id; stream> > ob.surname; stream> > ob.result; return stream; } Проверим работу с помощью следующего программного кода: void main(){ tArray < sportsmen> C(3); C.input(); //ввод с клавиатуры C.outputTFile(); //вывод в текстовый файл C.inputTFile(); //ввод из текстового файла C.output(); //вывод на экран } Если мы хотим, использовать бинарные файлы, то для работы с ними воспользуемся функциями: istream write(char *адрес переменной, число байт) – запись ostream read(const char *адрес переменной, число байт)- чтение. Создадим для класса sportsmen две функции, одна из которых будет сохранять объект в файловый поток в бинарном виде, а другая будет извлекать из потока в память. void sportsmen:: store(fstream & stream){//сохраняем в поток stream.write((char*)& id, sizeof(int)); //записываем идентификатор stream.write(surname, 10); //записываем фамилию stream.write((char*)& result, sizeof(int)); //записываем результат } void sportsmen:: retrive(fstream & stream){//извлекаем из потока stream.read((char*)& id, sizeof(int)); //считываем идентификатор stream.read(surname, 10); //считываем фамилию stream.read((char*)& result, sizeof(int)); //считываем результат } Далее необходимо организовать ввод/вывод массива объектов типа sportsmen в бинарный поток. Для этого мы не будем создавать в классе tArray шаблонные функции для ввода вывода элементов массива в бинарный файл. Данные функции должны будут использовать внутри себя, созданные выше функции помещения и извлечения объекта из бинарного потока, а они в свою очередь привязаны к объектам типа sportsmen и для массивов других типов, например int, не подойдут. Создадим класс sportsmenArray, который будет наследовать класс tArray c параметром типом < sportsmen> и содержать свои методы, которые строго привязаны к объектам типа sportsmen, в частности функции ввода/вывода элементов массива в бинарный файл. class sportsmenArray: public tArray< sportsmen> { public: sportsmenArray(int l): tArray< sportsmen> (l){}; //конструктор void inputBFile(char* filename); //ввод массива void outputBFile(char* filename); //вывод массива }; void sportsmenArray:: outputBFile(char* filename){ fstream out(filename, ios:: out | ios:: binary); if (! out){cout< < " Cann't open file " < < filename< < " for output! "; exit; } for (int i=0; i< n; i++){B[i].store(out); } out.close(); } void sportsmenArray:: inputBFile(char* filename){ fstream in(filename, ios:: in | ios:: binary); //инициализируем поток ввода if (! in){cout< < " Cann't open file " < < filename< < " for input! "; exit; } for (int i=0; i< n; i++){B[i].retrive(in); } in.close(); } Кроме того нам необходимо внести изменения в описание класса шаблона tArray. В классе потомке sportsmenArray необходимо получить доступ к свойствам родительского класса tArray массиву B и его размеру n. Для того чтобы это было возможно, необходимо чтобы эти свойства имели режим доступа protected. template < class typeArray> class tArray{ protected: typeArray B[SIZE]; int n; //размер массива …} Проверить работу можно с помощью такого программного кода. void main(){ sportsmenArray C(3); C.input(); //ввод с клавиатуры C.outputBFile(" test"); //вывод в текстовый файл C.inputBFile(" test"); //ввод из текстового файла C.output(); //вывод на экран }
|