《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);
	};
}
#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;
}
其实做完第六题,这个基本上改改就行了。。。



posted @ 2017-01-05 00:25  肥宝游戏  阅读(205)  评论(0编辑  收藏  举报