Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
53
Добавлен:
10.12.2013
Размер:
55.81 Кб
Скачать

Пермский государственный технический университет

Кафедра ИТАС

Лабораторная работа №7

Потоковые классы.

Выполнил студент гр. АСУ-01-2 Меньшиков А.Е.

Проверил доцент кафедры ИТАС

Ноткин А.М.

Пермь 2002.

Определение пользовательского класса:

static const number=20;

class employee

{

char name[number];//имя

int age;//возраст

int work;//стаж

public:

employee();//конструктор без параметров

employee(char[number],int,int);//конструктор с параметрами

employee(const employee&);//конструктор копирования

employee& operator=(const employee& ob);//оператор присваивания

~employee(){};//деструктор

const char* getname();//возвращает имя

int getage();//возвращает возраст

int getwork();//возвращает стаж

void putname(char[number]);//изменение имени

void putage(int);//изменение возраста

void putwork(int);//изменение стажа

friend ostream& operator<<(ostream& s,employee& ob);

friend istream& operator>>(istream& s,employee& ob);

};

employee::employee()

{

age=0;

work=0;

};

employee::employee(char N[number],int A,int W)

{

strcpy(name,N);

age=A;

work=W;

};

employee::employee(const employee& ob)

{

strcpy(name,ob.name);

age=ob.age;

work=ob.work;

};

employee& employee::operator =(const employee& ob)

{

if(&ob==this)return *this;

strcpy(name,ob.name);

age=ob.age;

work=ob.work;

return *this;

};

const char* employee::getname(){return name;};

int employee::getage(){return age;};

int employee::getwork(){return work;};

void employee::putname(char N[number]){strcpy(name,N);return;};

void employee::putage(int A){age=A;return;};

void employee::putwork(int W){work=W;return;};

ostream& operator<<(ostream& s,employee& ob)

{

s<<"name "<<wp(20,'.')<<ob.name<<"\nage "<<wp(21,'.')<<ob.age<<"\nwork "<<wp(20,'.')<<ob.work<<'\n';

return s;

};

istream& operator>>(istream& s,employee& ob)

{

cout<<"enter name ";s>>ob.name;

cout<<"enter age ";s>>ob.age;

cout<<"enter work ";s>>ob.work;

return s;

};

ofstream& operator<<(ofstream& s,employee& ob)

{

s.write((char*)&ob,sizeof(employee));

return s;

};

ifstream& operator>>(ifstream& s,employee& ob)

{

s.read((char*)&ob,sizeof(employee));

return s;

};

Программа №1.

Постановка задачи.

Написать программу для создания объектов пользовательского класса (ввод исходной

информации с клавиатуры с использованием перегруженной операции ">>") и сохранения их в потоке (файле). Предусмотреть в программе вывод сообщения о количестве сохраненных объектов и о длине полученного файла в байтах.

Реализация:

filebuf buf1;

if(!buf1.open("..\\file.emp",ios::out))

{cout<<"Error!";return (-1);};

ostream stream1(&buf1);

for(i=0;i<n;i++)

{

stream1.write((char*) &mas[i],sizeof(employee));

};

cout<<"Size of file.emp "<<stream1.tellp()<<" bytes."<<'\n';

cout<<"Save "<<stream1.tellp()/sizeof(employee)<<" objects."<<'\n';

В программе используется класс ostream.

Создается объект filebuf, связывается с файлом file.emp. Затем создается объект класса ostream и связывается с filebuf.

В поток записываются объекты класса employee из массива mas.

Реализация манипулятора:

class my_manip

{

int n;

char key;

ostream& (*f)(ostream&,int,char);

public:

my_manip(ostream& (*F)(ostream&,int,char),int N,char K):f(F),n(N),key(K){};

friend ostream& operator<<(ostream& s,my_manip ob)

{return ob.f(s,ob.n,ob.key);};

};

ostream& w(ostream& s,int n,char key)

{

s.width(n);

s.fill(key);

return s;

};

my_manip wp(int n,char key)

{return my_manip(w,n,key);};

В манипуляторе используются 2 поля: ширина поля вывода и символ-заполнитель.

Программа №2:

Написать программу для чтения объектов из потока, сохранения их в массиве и просмотр массива. Для просмотра объектов использовать перегруженную для cout операцию << и свой манипулятор. Предусмотреть в программе вывод сообщения о количестве прочитанных объектов и байтов.

Реализация:

ifstream stream2;

stream2.open("..\\file.emp",ios::binary);

if(!stream2){cout<<"Error";return (-1);};

int size,j;

stream2.seekg(0,ios::end);

size=stream2.tellg();cout<<"Size of file.emp "<<size<<" bytes.\n";

j=size/sizeof(employee);cout<<"Reading "<<j<<" objects.\n";

employee* p=new employee[j];

stream2.seekg(0,ios::beg);

for(int i=0;i<j;i++)

{

stream2>>p[i];

//stream2.read((char*) &p[i],sizeof(employee));

cout<<(i+1)<<" object\n"<<p[i];

};

stream2.close();

delete[] p;

В программе используется класс ifstream.

Сначала создается объект класса ifstream, который затем присоединяется к файлу file.emp. Объекты читаются в динамический массив p и выводятся на экран. Динамический массив создается на количество объектов, сохраненных в файле.

Программа №3:

Написать программу добавления нескольких объектов в поток и просмотра полученного файла.

Реализация:

ofstream stream3("..\\file.emp",ios::binary|ios::ate);

if(!stream3){cout<<"Error";return (-1);};

employee buf;

stream3.seekp(0,ios::end);

for(int i=0;i<2;i++)

{

cin>>buf;

stream3.write((char*)&buf,sizeof(employee));

};

stream3.close();

//out

ifstream stream2;

stream2.open("..\\file.emp",ios::binary);

if(!stream2){cout<<"Error";return (-1);};

stream2.seekg(0,ios::end);

int j=stream2.tellg()/sizeof(employee);

stream2.seekg(0,ios::beg);

cout<<"read\n";

for(i=0;i<j;i++)

{

stream2.read((char*)&buf,sizeof(employee));

cout<<buf;

};

stream2.close();

В программе используются классы ofstream (для добавления объектов в поток) и ifstream (для просмотра полученного файла).

Создается объект класса ofstream (в режиме ios::ate) и одновременно открывается файл file.emp. Считанные с клавиатуры объекты добавляются в поток.

Программа №4:

Написать программу для удаления обектов из файла и просмотра полученного файла.

Реализация:

cout<<"find "<<find("..\\file.emp","ivanov")<<'\n';

del("..\\file.emp","ivanov");

Реализация функции find():

long find(const char* file,const char* NAME)

{

ifstream stream(file,ios::binary);

if(!stream){cout<<"Error";return (-2);};

employee buf;

stream.seekg(0,ios::beg);

while(!stream.eof())

{

stream.read((char*) &buf,sizeof(employee));

if(strcmp(NAME,buf.getname())==0)

return (stream.tellg()-sizeof(employee));

};

return (-1);

};

Функция возвращает смещение объекта от начала файла, либо возвращает -1-если объект не найден, либо -2, если произошла ошибка открытия файла.

Реализация функции del():

int del(const char* file,const char* NAME)

{

long f=find(file,NAME);

if(f<0)return 0;

fstream stream1(file,ios::in|ios::binary);

if(!stream1){cout<<"Error";return(-1);};

fstream stream2("..\\file.txt",ios::out|ios::binary);

if(!stream2){cout<<"Error";return (-1);};

employee buf;

stream1.seekg(0,ios::end);

long size=stream1.tellg()/sizeof(employee);

stream1.seekg(0,ios::beg);

for(int i=0;i<size;i++)

{

stream1.read((char*)&buf,sizeof(employee));

if(stream1.tellg()!=(f+sizeof(employee)))

stream2.write((char*)&buf,sizeof(employee));

else cout<<"Deleting object:\n"<<buf;

};

stream1.close();

stream2.close();

rename(file,"..\\temp");

rename("..\\file.txt",file);

rename("..\\temp","..\\file.txt");

stream1.open("..\\file.txt",ios::out|ios::binary);

stream1.close();

return 0;

};

Функция возвращает -1, если произошла ошибка открытия файла, 0 - объект не найден, 1 - объект успешно удален.

Программа №5:

Написать программу корректировки (т.е. замены) записей в файле и просмотра полученного файла.

Реализация функции repl():

int repl(const char* file,const char* NAME)

{

long f=find(file,NAME);

if(f<0)return 0;

fstream stream(file,ios::in|ios::out|ios::binary);

if(!stream){cout<<"Error";exit(-1);};

employee buf;

stream.seekp(f,ios::beg);

stream.read((char*)&buf,sizeof(employee));

cout<<"Deleting object:\n"<<buf<<'\n';

cout<<"enter new object\n";

cin>>buf;

stream.seekp(f,ios::beg);

stream.write((char*)&buf,sizeof(employee));

return 1;

};

Функция создает объект класса fstream и открывает файл в режиме ios::in|ios::out|ios::binary, выводит на экран изменяемый объект и записывает на его место новый объект.

13