Программирование / Лабораторные / АСУ_Лаб7_С++_Ноткин / АСУ_Лаб7_С++_Ноткин
.docПермский государственный технический университет
Кафедра ИТАС
Лабораторная работа №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, выводит на экран изменяемый объект и записывает на его место новый объект.