《C++ Primer Plus(第六版)》(42)(第十七章 输入、输出和文件 编程练习和答案2)
重点:文件读写,二进制文件读写,
题目好长,分多一张
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); }; } #endifTest.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); }; } #endifTest.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; }其实做完第六题,这个基本上改改就行了。。。