重点:文件读写,二进制文件读写,
题目好长,分多一张
6.考虑14章的编程练习5中的类定义。如果还没有完成这个练习,请现在就做,然后完成下面的任务。
编写一个程序,它使用标准C++I/O、文件I/O以及14章的变成练习5中定义的employee、manager、fink和highfink类型的数据。该程序赢包含程序清单17.17中的代码行,即允许用户将新数据添加到文件中。当该程序首次被运行时,将要求用户输入数据,然后显示所有的数据,并将这些信息保存到一个文件中。当该程序再次被运行时,将首先读取并显示文件中的数据,然后让用户添加数据,并显示所有的数据。差别之一是,应通过一个指向employee类型的指针数组来处理数据。这样,指针可以指向employee对象,也可以指向从employee派生出来的其他三种对象的任何一种。使数组较小有助于检查程序,例如,您可能将数组限定为最多包含10个元素:
const int MAX = 10;
。。。
employee * pc[MAX];
为通过键盘输入,程序应使用一个菜单,让用户选择要创建的对象类型。菜单将使用一个switch,以便使用new来创建指定类型的对象,并将它的地址赋给pc数组中的一个指针。然后该对象可以使用虚函数setall()来提示用户输入相应的数据:
pc[i]->setall();
为将数据保存到文件中,应设计一个虚函数writeall();
for(int i = 0; i < index; i++)
pc[i]->writeall(fout);
注意:对于这个练习,应使用文本I/O,而不是二进制I/O(遗憾的是,虚对象包含向虚函数指针表的指针,而write()将把这种信息复制到文件中。使用read()读取文件的内容,以填充对象时,函数指针值将为乱码,这将扰乱虚函数的行为)。可使用换行符将字段分隔开,这样在输入时将很容易识别各个字段。也可以使用二进制I/O,但不能将对象作为一个整体写入,应应该提供分别对每个类成员应用write()和read()的类方法。这样程序只把所需的数据保存到文件中。
比较难处理的部分是使用文件恢复数据。问题在于:程序如何才能知道接下来要恢复的项目是employee对象、manager对象、fink对象还是HighFink对象?一种方法是,在对象数据写入文件时,在数据前面加上一个指示对象类型的整数。这样,在函数输入时,程序便可以读取该整数,并使用switch语句创建一个适当的对象来接收数据:
enum classkind{Employee, Manager, Fink, HighFink};
。。。
int classtype;
while((fin>>classtype).get(ch))
{
switch(classtype)
{
case Employee: pc[i] = new employee;
break;
}
}
然后便可以使用指针调用虚函数getall()来读取信息:
pc[i++]->getall();
先来个文本格式保存的代码:
Test.h
//
// Test.h
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#ifndef _Test_H_
#define _Test_H_
#include <iostream>
#include <string>
using namespace std;
namespace FableGame
{
enum EEmployeeType
{
EEmployeeType_Normal = 1,
EEmployeeType_Manager = 2,
EEmployeeType_Fink = 3,
EEmployeeType_HighFink = 4,
};
class AbstrEmp
{
private:
string _fname;
string _lname;
string _job;
protected:
void setData();
void showData()const;
istream& readData(istream& is);
ostream& writeData(ostream& os);
public:
AbstrEmp();
AbstrEmp(const std::string& fn, const string& ln, const string& j);
virtual void showAll()const;
virtual void setAll();
friend ostream& operator<<(ostream& os, const AbstrEmp& e);
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
virtual ~AbstrEmp();
};
class Employee : virtual public AbstrEmp
{
public:
Employee();
Employee(const string& fn, const string& ln, const string& j);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
class Manager : virtual public AbstrEmp
{
private:
int _inchargeof;
protected:
int inChargeOf()const
{
return _inchargeof;
}
int& inChargeOf()
{
return _inchargeof;
}
void setData();
void showData()const;
istream& readData(istream& is);
ostream& writeData(ostream& os);
public:
Manager();
Manager(const string& fn, const string& ln, const string& j0, int ico = 0);
Manager(const AbstrEmp& e, int ico);
Manager(const Manager& m);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
class Fink : virtual public AbstrEmp
{
private:
string _reportsto;
protected:
const string reportsTo() const{ return _reportsto; }
string& reportsTo(){ return _reportsto; }
void setData();
void showData()const;
istream& readData(istream& is);
ostream& writeData(ostream& os);
public:
Fink();
Fink(const string& fn, const string& ln, const string& j, const string& rpo);
Fink(const AbstrEmp& e, const string& rpo);
Fink(const Fink& e);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
class HighFink : public Manager, public Fink
{
public:
HighFink();
HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico);
HighFink(const AbstrEmp& e, const string& rpo, int ico);
HighFink(const Fink& f, int ico);
HighFink(const Manager& m, const string& rpo);
HighFink(const HighFink& h);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
}
#endif
Test.cpp
//
// Test.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include "Test.h"
#include <iostream>
using namespace std;
using namespace FableGame;
FableGame::AbstrEmp::AbstrEmp()
{
_fname = "";
_lname = "";
_job = "";
}
FableGame::AbstrEmp::AbstrEmp(const std::string& fn, const string& ln, const string& j)
{
_fname = fn;
_lname = ln;
_job = j;
}
void FableGame::AbstrEmp::showAll() const
{
showData();
}
void FableGame::AbstrEmp::setAll()
{
setData();
}
FableGame::AbstrEmp::~AbstrEmp()
{
}
void FableGame::AbstrEmp::showData()const
{
cout << "FName:" << _fname << " LName:" << _lname << " Job:" << _job << endl;
}
void FableGame::AbstrEmp::setData()
{
cout << "Enter FName:";
getline(cin, _fname);
cout << "Enter LName:";
getline(cin, _lname);
cout << "Enter Job:";
getline(cin, _job);
}
istream& FableGame::AbstrEmp::readAll(istream& is)
{
readData(is);
return is;
}
ostream& FableGame::AbstrEmp::writeAll(ostream& os)
{
writeData(os);
return os;
}
istream& FableGame::AbstrEmp::readData(istream& is)
{
getline(is, _fname);
getline(is, _lname);
getline(is, _job);
return is;
}
ostream& FableGame::AbstrEmp::writeData(ostream& os)
{
os << _fname << endl;
os << _lname << endl;
os << _job << endl;
return os;
}
ostream& FableGame::operator<<(ostream& os, const AbstrEmp& e)
{
os << e._fname << " " << e._lname << " " << e._job;
return os;
}
FableGame::Employee::Employee()
{
}
FableGame::Employee::Employee(const string& fn, const string& ln, const string& j) : AbstrEmp(fn, ln, j)
{
}
void FableGame::Employee::showAll() const
{
AbstrEmp::showData();
}
void FableGame::Employee::setAll()
{
AbstrEmp::setData();
}
istream& FableGame::Employee::readAll(istream& is)
{
AbstrEmp::readData(is);
return is;
}
ostream& FableGame::Employee::writeAll(ostream& os)
{
os << EEmployeeType_Normal << endl;
AbstrEmp::writeData(os);
return os;
}
FableGame::Manager::Manager()
{
_inchargeof = 0;
}
FableGame::Manager::Manager(const string& fn, const string& ln, const string& j0, int ico /*= 0*/) : AbstrEmp(fn, ln, j0), _inchargeof(ico)
{
}
FableGame::Manager::Manager(const AbstrEmp& e, int ico) : AbstrEmp(e), _inchargeof(ico)
{
}
FableGame::Manager::Manager(const Manager& m) : AbstrEmp(m)
{
_inchargeof = m._inchargeof;
}
void FableGame::Manager::showAll() const
{
AbstrEmp::showData();
showData();
}
void FableGame::Manager::setAll()
{
AbstrEmp::setData();
setData();
}
void FableGame::Manager::setData()
{
cout << "Enter inchargeof:";
cin >> _inchargeof;
cin.get();
}
void FableGame::Manager::showData() const
{
cout << "inchargeof:" << _inchargeof << endl;
}
istream& FableGame::Manager::readData(istream& is)
{
is >> _inchargeof;
is.get();
return is;
}
ostream& FableGame::Manager::writeData(ostream& os)
{
os << _inchargeof << endl;
return os;
}
istream& FableGame::Manager::readAll(istream& is)
{
AbstrEmp::readAll(is);
readData(is);
return is;
}
ostream& FableGame::Manager::writeAll(ostream& os)
{
os << EEmployeeType_Manager << endl;
AbstrEmp::writeData(os);
writeData(os);
return os;
}
FableGame::Fink::Fink()
{
}
FableGame::Fink::Fink(const string& fn, const string& ln, const string& j, const string& rpo) : AbstrEmp(fn, ln, j), _reportsto(rpo)
{
}
FableGame::Fink::Fink(const AbstrEmp& e, const string& rpo) : AbstrEmp(e), _reportsto(rpo)
{
}
FableGame::Fink::Fink(const Fink& e) : AbstrEmp(e)
{
_reportsto = e._reportsto;
}
void FableGame::Fink::showAll() const
{
AbstrEmp::showData();
showData();
}
void FableGame::Fink::setAll()
{
AbstrEmp::setData();
setData();
}
void FableGame::Fink::setData()
{
cout << "Enter _reportsto:";
cin >> _reportsto;
cin.get();
}
void FableGame::Fink::showData() const
{
cout << "reportsto:" << _reportsto << endl;
}
istream& FableGame::Fink::readData(istream& is)
{
getline(is, _reportsto);
return is;
}
ostream& FableGame::Fink::writeData(ostream& os)
{
os << _reportsto;
return os;
}
istream& FableGame::Fink::readAll(istream& is)
{
AbstrEmp::readData(is);
readData(is);
return is;
}
ostream& FableGame::Fink::writeAll(ostream& os)
{
os << EEmployeeType_Fink << endl;
AbstrEmp::writeData(os);
writeData(os);
return os;
}
FableGame::HighFink::HighFink()
{
}
FableGame::HighFink::HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico) :
AbstrEmp(fn, ln, j), Manager(fn, ln, j, ico), Fink(fn, ln, j, rpo)
{
}
FableGame::HighFink::HighFink(const AbstrEmp& e, const string& rpo, int ico) :AbstrEmp(e), Manager(e, ico), Fink(e, rpo)
{
}
FableGame::HighFink::HighFink(const Fink& f, int ico) : Fink(f), Manager(f, ico), AbstrEmp(f)
{
}
FableGame::HighFink::HighFink(const Manager& m, const string& rpo) : Fink(m, rpo), Manager(m), AbstrEmp(m)
{
}
FableGame::HighFink::HighFink(const HighFink& h) : Fink(h), Manager(h), AbstrEmp(h)
{
}
void FableGame::HighFink::showAll() const
{
AbstrEmp::showData();
Manager::showData();
Fink::showData();
}
void FableGame::HighFink::setAll()
{
AbstrEmp::setData();
Manager::setData();
Fink::setData();
}
istream& FableGame::HighFink::readAll(istream& is)
{
AbstrEmp::readData(is);
Manager::readData(is);
Fink::readData(is);
return is;
}
ostream& FableGame::HighFink::writeAll(ostream& os)
{
os << EEmployeeType_HighFink << endl;
AbstrEmp::writeAll(os);
Manager::writeAll(os);
Fink::writeAll(os);
return os;
}
main.cpp
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 17/01/04.
// Copyright (c) 2016年 Fable. All rights reserved.
//
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include "Test.h"
using namespace std;
using namespace FableGame;
void readFileData(ifstream& fin, vector<AbstrEmp*>& employees)
{
int employeeType = 0;
while (fin && fin >> employeeType)
{
fin.get();
AbstrEmp* temp;
switch (employeeType)
{
case 1:
temp = new Employee();
break;
case 2:
temp = new Manager();
break;
case 3:
temp = new Fink();
break;
case 4:
temp = new HighFink();
break;
default:
return;
}
temp->readAll(fin);
employees.push_back(temp);
}
}
void writeFileData(ofstream& fout, vector<AbstrEmp*> employees)
{
for (vector<AbstrEmp*>::iterator iter = employees.begin();
iter != employees.end();
iter ++)
{
(*iter)->writeAll(fout);
}
}
int main(int argc, char* argv[])
{
if (argc == 1)
{
cerr << "Usage: " << argv[0] << "readFileName[s] writeFileName\n";
exit(EXIT_FAILURE);
}
ifstream fin;
vector<AbstrEmp*> es;
//打开文件输入数据
for (int file = 1; file < argc - 1; file++)
{
fin.open(argv[file]);
if (!fin.is_open())
{
cerr << "Could not open " << argv[file] << endl;
fin.clear();
continue;
}
readFileData(fin, es);
fin.clear();
fin.close();
}
//展示现有的数据
cout << "===================old all data ======================" << endl;
for (vector<AbstrEmp*>::iterator iter = es.begin(); iter != es.end(); ++iter)
{
(*iter)->showAll();
}
//让用户输入数据
cout << "Enter new employee type: 1.normal employee, 2.manager,\n"
<< "3.fink, 4.high fink, other to quit:";
int empType = 0;
AbstrEmp* temp;
while (cin && cin >> empType)
{
cin.get();
temp = nullptr;
switch (empType)
{
case 1:
temp = new Employee();
break;
case 2:
temp = new Manager();
break;
case 3:
temp = new Fink();
break;
case 4:
temp = new HighFink();
break;
}
if (temp)
{
temp->setAll();
es.push_back(temp);
cout << "Enter new employee type: 1.normal employee, 2.manager,\n"
<< "3.fink, 4.high fink, other to quit:";
}
else
{
break;
}
}
ofstream fout(argv[argc - 1]);
if (fout.is_open())
{
writeFileData(fout, es);
}
//展示现有的数据
cout << "===================new all data ======================" << endl;
for (vector<AbstrEmp*>::iterator iter = es.begin(); iter != es.end(); ++iter)
{
(*iter)->showAll();
}
for (vector<AbstrEmp*>::iterator iter = es.begin(); iter != es.end(); ++iter)
{
delete *iter;
}
fout.close();
return 0;
}
改成二进制格式保存
Test.h
//
// Test.h
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#ifndef _Test_H_
#define _Test_H_
#include <iostream>
#include <string>
using namespace std;
namespace FableGame
{
istream& read(istream& is, int& i);
ostream& write(ostream& os, int i);
istream& read(istream& is, string& str);
ostream& write(ostream& os, string& str);
enum EEmployeeType
{
EEmployeeType_Normal = 1,
EEmployeeType_Manager = 2,
EEmployeeType_Fink = 3,
EEmployeeType_HighFink = 4,
};
class AbstrEmp
{
private:
string _fname;
string _lname;
string _job;
protected:
void setData();
void showData()const;
istream& readData(istream& is);
ostream& writeData(ostream& os);
public:
AbstrEmp();
AbstrEmp(const std::string& fn, const string& ln, const string& j);
virtual void showAll()const;
virtual void setAll();
friend ostream& operator<<(ostream& os, const AbstrEmp& e);
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
virtual ~AbstrEmp();
};
class Employee : virtual public AbstrEmp
{
public:
Employee();
Employee(const string& fn, const string& ln, const string& j);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
class Manager : virtual public AbstrEmp
{
private:
int _inchargeof;
protected:
int inChargeOf()const
{
return _inchargeof;
}
int& inChargeOf()
{
return _inchargeof;
}
void setData();
void showData()const;
istream& readData(istream& is);
ostream& writeData(ostream& os);
public:
Manager();
Manager(const string& fn, const string& ln, const string& j0, int ico = 0);
Manager(const AbstrEmp& e, int ico);
Manager(const Manager& m);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
class Fink : virtual public AbstrEmp
{
private:
string _reportsto;
protected:
const string reportsTo() const{ return _reportsto; }
string& reportsTo(){ return _reportsto; }
void setData();
void showData()const;
istream& readData(istream& is);
ostream& writeData(ostream& os);
public:
Fink();
Fink(const string& fn, const string& ln, const string& j, const string& rpo);
Fink(const AbstrEmp& e, const string& rpo);
Fink(const Fink& e);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
class HighFink : public Manager, public Fink
{
public:
HighFink();
HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico);
HighFink(const AbstrEmp& e, const string& rpo, int ico);
HighFink(const Fink& f, int ico);
HighFink(const Manager& m, const string& rpo);
HighFink(const HighFink& h);
virtual void showAll()const;
virtual void setAll();
virtual istream& readAll(istream& is);
virtual ostream& writeAll(ostream& os);
};
}
#endif
Test.cpp
//
// Test.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include "Test.h"
#include <iostream>
using namespace std;
using namespace FableGame;
//读写函数封装
istream& FableGame::read(istream& is, string& str)
{
size_t l = 0;
is.read((char*)&l, sizeof(size_t));
char* ch = new char[l+1];
is.read(ch, l);
str = ch;
delete [] ch;
return is;
}
ostream& FableGame::write(ostream& os, string& str)
{
size_t l = str.length();
os.write((char*)&l, sizeof(size_t));
os.write(str.c_str(), str.length());
return os;
}
istream& FableGame::read(istream& is, int& i)
{
return is.read((char*)&i, sizeof(int));
}
ostream& FableGame::write(ostream& os, int i)
{
return os.write((char*)&i, sizeof(int));
}
FableGame::AbstrEmp::AbstrEmp()
{
_fname = "";
_lname = "";
_job = "";
}
FableGame::AbstrEmp::AbstrEmp(const std::string& fn, const string& ln, const string& j)
{
_fname = fn;
_lname = ln;
_job = j;
}
void FableGame::AbstrEmp::showAll() const
{
showData();
}
void FableGame::AbstrEmp::setAll()
{
setData();
}
FableGame::AbstrEmp::~AbstrEmp()
{
}
void FableGame::AbstrEmp::showData()const
{
cout << "FName:" << _fname << " LName:" << _lname << " Job:" << _job << endl;
}
void FableGame::AbstrEmp::setData()
{
cout << "Enter FName:";
getline(cin, _fname);
cout << "Enter LName:";
getline(cin, _lname);
cout << "Enter Job:";
getline(cin, _job);
}
istream& FableGame::AbstrEmp::readAll(istream& is)
{
readData(is);
return is;
}
ostream& FableGame::AbstrEmp::writeAll(ostream& os)
{
writeData(os);
return os;
}
istream& FableGame::AbstrEmp::readData(istream& is)
{
read(is, _fname);
read(is, _lname);
read(is, _job);
// getline(is, _fname);
// getline(is, _lname);
// getline(is, _job);
return is;
}
ostream& FableGame::AbstrEmp::writeData(ostream& os)
{
write(os, _fname);
write(os, _lname);
write(os, _job);
// os << _fname << endl;
// os << _lname << endl;
// os << _job << endl;
return os;
}
ostream& FableGame::operator<<(ostream& os, const AbstrEmp& e)
{
os << e._fname << " " << e._lname << " " << e._job;
return os;
}
FableGame::Employee::Employee()
{
}
FableGame::Employee::Employee(const string& fn, const string& ln, const string& j) : AbstrEmp(fn, ln, j)
{
}
void FableGame::Employee::showAll() const
{
AbstrEmp::showData();
}
void FableGame::Employee::setAll()
{
AbstrEmp::setData();
}
istream& FableGame::Employee::readAll(istream& is)
{
AbstrEmp::readData(is);
return is;
}
ostream& FableGame::Employee::writeAll(ostream& os)
{
write(os, EEmployeeType_Normal);
AbstrEmp::writeData(os);
return os;
}
FableGame::Manager::Manager()
{
_inchargeof = 0;
}
FableGame::Manager::Manager(const string& fn, const string& ln, const string& j0, int ico /*= 0*/) : AbstrEmp(fn, ln, j0), _inchargeof(ico)
{
}
FableGame::Manager::Manager(const AbstrEmp& e, int ico) : AbstrEmp(e), _inchargeof(ico)
{
}
FableGame::Manager::Manager(const Manager& m) : AbstrEmp(m)
{
_inchargeof = m._inchargeof;
}
void FableGame::Manager::showAll() const
{
AbstrEmp::showData();
showData();
}
void FableGame::Manager::setAll()
{
AbstrEmp::setData();
setData();
}
void FableGame::Manager::setData()
{
cout << "Enter inchargeof:";
cin >> _inchargeof;
cin.get();
}
void FableGame::Manager::showData() const
{
cout << "inchargeof:" << _inchargeof << endl;
}
istream& FableGame::Manager::readData(istream& is)
{
return read(is, _inchargeof);
}
ostream& FableGame::Manager::writeData(ostream& os)
{
return write(os, _inchargeof);
}
istream& FableGame::Manager::readAll(istream& is)
{
AbstrEmp::readAll(is);
readData(is);
return is;
}
ostream& FableGame::Manager::writeAll(ostream& os)
{
write(os, EEmployeeType_Manager);
AbstrEmp::writeData(os);
writeData(os);
return os;
}
FableGame::Fink::Fink()
{
}
FableGame::Fink::Fink(const string& fn, const string& ln, const string& j, const string& rpo) : AbstrEmp(fn, ln, j), _reportsto(rpo)
{
}
FableGame::Fink::Fink(const AbstrEmp& e, const string& rpo) : AbstrEmp(e), _reportsto(rpo)
{
}
FableGame::Fink::Fink(const Fink& e) : AbstrEmp(e)
{
_reportsto = e._reportsto;
}
void FableGame::Fink::showAll() const
{
AbstrEmp::showData();
showData();
}
void FableGame::Fink::setAll()
{
AbstrEmp::setData();
setData();
}
void FableGame::Fink::setData()
{
cout << "Enter reportsto:";
cin >> _reportsto;
cin.get();
}
void FableGame::Fink::showData() const
{
cout << "reportsto:" << _reportsto << endl;
}
istream& FableGame::Fink::readData(istream& is)
{
return read(is, _reportsto);
}
ostream& FableGame::Fink::writeData(ostream& os)
{
return write(os, _reportsto);
}
istream& FableGame::Fink::readAll(istream& is)
{
AbstrEmp::readData(is);
readData(is);
return is;
}
ostream& FableGame::Fink::writeAll(ostream& os)
{
write(os, EEmployeeType_Fink);
AbstrEmp::writeData(os);
writeData(os);
return os;
}
FableGame::HighFink::HighFink()
{
}
FableGame::HighFink::HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico) :
AbstrEmp(fn, ln, j), Manager(fn, ln, j, ico), Fink(fn, ln, j, rpo)
{
}
FableGame::HighFink::HighFink(const AbstrEmp& e, const string& rpo, int ico) :AbstrEmp(e), Manager(e, ico), Fink(e, rpo)
{
}
FableGame::HighFink::HighFink(const Fink& f, int ico) : Fink(f), Manager(f, ico), AbstrEmp(f)
{
}
FableGame::HighFink::HighFink(const Manager& m, const string& rpo) : Fink(m, rpo), Manager(m), AbstrEmp(m)
{
}
FableGame::HighFink::HighFink(const HighFink& h) : Fink(h), Manager(h), AbstrEmp(h)
{
}
void FableGame::HighFink::showAll() const
{
AbstrEmp::showData();
Manager::showData();
Fink::showData();
}
void FableGame::HighFink::setAll()
{
AbstrEmp::setData();
Manager::setData();
Fink::setData();
}
istream& FableGame::HighFink::readAll(istream& is)
{
AbstrEmp::readData(is);
Manager::readData(is);
Fink::readData(is);
return is;
}
ostream& FableGame::HighFink::writeAll(ostream& os)
{
write(os, EEmployeeType_HighFink);
AbstrEmp::writeAll(os);
Manager::writeAll(os);
Fink::writeAll(os);
return os;
}
main.cpp
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 17/01/04.
// Copyright (c) 2016年 Fable. All rights reserved.
//
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include "Test.h"
using namespace std;
using namespace FableGame;
void readFileData(ifstream& fin, vector<AbstrEmp*>& employees)
{
int employeeType = 0;
AbstrEmp* temp;
while (fin && read(fin, employeeType))
{
temp = NULL;
switch (employeeType)
{
case 1:
temp = new Employee();
break;
case 2:
temp = new Manager();
break;
case 3:
temp = new Fink();
break;
case 4:
temp = new HighFink();
break;
}
if (!temp)
{
break;
}
temp->readAll(fin);
employees.push_back(temp);
}
}
void writeFileData(ofstream& fout, vector<AbstrEmp*> employees)
{
for (vector<AbstrEmp*>::iterator iter = employees.begin();
iter != employees.end();
iter ++)
{
(*iter)->writeAll(fout);
}
}
int main(int argc, char* argv[])
{
if (argc == 1)
{
cerr << "Usage: " << argv[0] << "readFileName[s] writeFileName\n";
exit(EXIT_FAILURE);
}
ifstream fin;
vector<AbstrEmp*> es;
//打开文件输入数据
for (int file = 1; file < argc - 1; file++)
{
fin.open(argv[file], ios::in | ios::binary);
if (!fin.is_open())
{
cerr << "Could not open " << argv[file] << endl;
fin.clear();
continue;
}
readFileData(fin, es);
fin.clear();
fin.close();
}
//展示现有的数据
cout << "===================old all data ======================" << endl;
for (vector<AbstrEmp*>::iterator iter = es.begin(); iter != es.end(); ++iter)
{
(*iter)->showAll();
}
//让用户输入数据
cout << "Enter new employee type: 1.normal employee, 2.manager,\n"
<< "3.fink, 4.high fink, other to quit:";
int empType = 0;
AbstrEmp* temp;
while (cin && cin >> empType)
{
cin.get();
temp = nullptr;
switch (empType)
{
case 1:
temp = new Employee();
break;
case 2:
temp = new Manager();
break;
case 3:
temp = new Fink();
break;
case 4:
temp = new HighFink();
break;
}
if (temp)
{
temp->setAll();
es.push_back(temp);
cout << "Enter new employee type: 1.normal employee, 2.manager,\n"
<< "3.fink, 4.high fink, other to quit:";
}
else
{
break;
}
}
ofstream fout(argv[argc - 1], ios::out | ios::binary);
if (fout.is_open())
{
writeFileData(fout, es);
}
//展示现有的数据
cout << "===================new all data ======================" << endl;
for (vector<AbstrEmp*>::iterator iter = es.begin(); iter != es.end(); ++iter)
{
(*iter)->showAll();
}
for (vector<AbstrEmp*>::iterator iter = es.begin(); iter != es.end(); ++iter)
{
delete *iter;
}
fout.close();
return 0;
}
这个代码写了好久,很多细节要注意。
1,打开文件的方式要注意,是二进制的。
2,读写要对应,最好把读写的代码放在一起对照。
3,写入了什么数据,就要读什么数据,数据格式要注意。这个研究好好久,感觉这是第一次跟机器的思想这么接近。从人类的角度来看int,size_t,long等都差不多,但是这这个时候,写进去,再读出来,你会发现数组千差万别。所以要写了什么,就要读什么,不能有丝毫偏差。
4,我封装了两个读写函数,感觉很方便,不知道库函数或者其他地方,有没有类似的写法,将基础类型封装一次。
5,这个东西跟之前我看网络的东西好像,细细想想,网路也是一种输入输出。现在如果再去重温,估计很容易看得懂了把。
7.下面是某个程序的部分代码。该程序将键盘输入读取到一个由string对象组成的vector中,将字符串内容(而不是string对象)存储到一个文件中,然后该文件的内容复制到另一个由string对象组成的vector中。
int main(int argc, char* argv[])
{
vector<string> vostr;
string temp;
cout << "Enter strings (empty line to quit):\n";
while (getline(cin, temp) && temp[0] != '\0') {
vostr.push_back(temp);
}
cout << "Here is you input.\n";
for_each(vostr.begin(), vostr.end(), showStr);
ofstream fout("strings.dat", ios_base::out | ios_base::binary);
for_each(vostr.begin(), vostr.end(), store(fout));
fout.close();
vector<string> vistr;
ifstream fin("strings.dat", ios_base::in| ios_base::binary);
if(!fin.is_open())
{
cerr << "Could not open file input.\n";
exit(EXIT_FAILURE);
}
getStrs(fin, vistr);
cout << "\nHere are the strings read from the file:\n";
for_each(vistr.begin(), vistr.end(), showStr);
return 0;
}
该程序以二进制格式打开文件,并想使用read()和write()来完成I/O。余下的工作如下所述。
·编写函数void showStr(const string&),它显示一个string对象,并在显示完成后换行。
·编写函数符Store,它将字符串信息写入到文件中。Store的构造函数应接受一个指定的ifstream对象的参数,而重载的operator()(const string&)应指出写入到文件中的字符串。一种可行的计划是,首先将字符串的长度写入文件中,然后将字符串的内容写入到文件中。例如,如果len存储了字符串的长度,可以这样做:
os.write((char*)&len, sizeof(std::size_t);
os.write(s.data(),len);
成员函数data()返回一个指针,该指针指向一个其中存储了字符串中字符的数组。它类似于成员函数c_str(),只是后者在数组末尾加上了一个空字符。
·编写函数getStrs(),它根据文件恢复信息。该函数可以使用read()来获得字符串的长度,然后使用一个循环从文件中读取相应的数量的字符,并将它们附加到一个原来为空的临时string末尾。优于string的数据是私有的,因此必须使用string类的方法来讲数据存储到string对象中,而不是直接存储。
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 17/01/04.
// Copyright (c) 2016年 Fable. All rights reserved.
//
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include "Test.h"
using namespace std;
using namespace FableGame;
istream& read(istream& is, string& str)
{
str.clear();
size_t l = 0;
is.read((char*)&l, sizeof(size_t));
char ch;
for(size_t i = 0; i < l; i++)
{
is.read(&ch, 1);
str.append(&ch);
}
return is;
}
ostream& write(ostream& os, const string& str)
{
size_t l = str.length();
os.write((char*)&l, sizeof(size_t));
os.write(str.data(), str.length());
return os;
}
void showStr(const string& str)
{
cout << str << endl;
}
struct store
{
ostream* _os;
store(ostream& os): _os(&os){}
void operator()(const string& str)
{
write(*_os, str);
}
};
void getStrs(istream& is, vector<string>& ss)
{
string temp;
while (is && read(is, temp)) {
ss.push_back(temp);
}
}
int main(int argc, char* argv[])
{
vector<string> vostr;
string temp;
cout << "Enter strings (empty line to quit):\n";
while (getline(cin, temp) && temp[0] != '\0') {
vostr.push_back(temp);
}
cout << "Here is you input.\n";
for_each(vostr.begin(), vostr.end(), showStr);
ofstream fout("strings.dat", ios_base::out | ios_base::binary);
for_each(vostr.begin(), vostr.end(), store(fout));
fout.close();
vector<string> vistr;
ifstream fin("strings.dat", ios_base::in| ios_base::binary);
if(!fin.is_open())
{
cerr << "Could not open file input.\n";
exit(EXIT_FAILURE);
}
getStrs(fin, vistr);
cout << "\nHere are the strings read from the file:\n";
for_each(vistr.begin(), vistr.end(), showStr);
return 0;
}
其实做完第六题,这个基本上改改就行了。。。