【第十七章】C++ Primer plus 的编程练习题

/***********************************
	2017年12月26日10:42:09
	Athor:xiyuan255
	Course:C++
	Contain:pe17-1.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十七章的第一题练习题
		 【 参考 P792 】
*************************************/
// pe17-1.cpp -- using get(char *, int, char);
#include <iostream>

int main()
{
	using std::cout;
	using std::cin;
	using std::endl;

	// 方法一:
	cout << "请输入一个字符串,计算$之前的字符数:\n";
	int count = 0;
	while (cin.peek() != '$') { // peek()并不从输入流中抽取数据,只是查看下一个字符
		cin.get(); // 从输入流中抽取一个字符
		count++;
	}
	cout << "输入流中第一个$之前的字符数目 = " << count << endl;
	cout << "输入流中下一个字符是:" << char(cin.get()) << endl;

#if 0
	// 方法二:
	cout << "请输入一个字符串,计算$之前的字符数:\n";
	const int LIM = 255;
	char temp[LIM];
	cin.get(temp, LIM, '$');

	cout << "输入流中第一个$之前的字符数目 = " << strlen(temp) << endl;
	cout << "输入流中下一个字符是:" << char(cin.get()) << endl;
#endif


	return 0;
}

/**
输出结果:
	请输入一个字符串,计算$之前的字符数:
	hjksdvnds41sju'$uvgdjks$
	输入流中第一个$之前的字符数目 = 15
*/

/***********************************
	2017年12月26日11:12:35
	Athor:xiyuan255
	Course:C++
	Contain:pe17-2.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十七章的第二题练习题
		 【 参考 P792 】
*************************************/
// pe17-2.cpp -- using 命令行将键盘输入内容转换到文件中
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>

int main(int argc, char * argv[])
{
	using namespace std;

	char filename[40];
	// 方法一:
	//cout << "请输入文件名:";
	//cin.getline(filename, 40);

	// 方法二:
	if (argc != 2) {
	    cout << "输入参数有误!\n";
		exit(EXIT_FAILURE);
	}
	strcpy(filename, argv[1]);


	ofstream fout(filename);

	if (!fout.is_open()) {
		cout << "文件打开失败!\n";
		exit(EXIT_FAILURE);
	}
	string temp;
	cout << "从键盘输入一些信息(输入空行退出):\n";
	while (getline(cin, temp) && temp.size() > 0) {  // 这里不能temp[0] != '\0'
		                        // 作为空行判断条件,因为当输入空行时,string
		                        // 对象的长度为0,没有temp[0]这个成员
		fout << temp << endl;
	}
	fout.close();

	return 0;
}

/**
输出结果:
	请输入文件名:copy.txt
	从键盘输入一些信息(输入空行退出):
	你好!欢迎来到C++学习课程!!
	我们来学习第十七章I/O流!

*/

// copy.txt
你好!欢迎来到C++学习课程!!
我们来学习第十七章I/O流!

/***********************************
	2017年12月26日11:39:31
	Athor:xiyuan255
	Course:C++
	Contain:pe17-3.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十七章的第三题练习题
		 【 参考 P792 】
*************************************/
// pe17-3.cpp -- using 命令行将键盘输入内容转换到文件中
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>

int main(int argc, char * argv[])
{
	using namespace std;

	if (argc != 3) {
	    cout << "输入参数有误!\n";
		exit(EXIT_FAILURE);
	}
	ifstream fin(argv[1], ios_base::in);
	ofstream fout(argv[2], ios_base::out);

	if (!(fin.is_open()||(fout.is_open()))) {
		cout << "文件打开失败!\n";
		exit(EXIT_FAILURE);
	}
	string temp;
	while (getline(fin, temp)) {  
		cout << temp << endl;
		fout << temp << endl;
	}

	if(fin.eof())
		cout << "读取完毕!\n";
	else if (fin.fail()) 
		cout << "读取异常!\n";
	else if (fin.bad()) 
		cout << "硬件故障!\n";

	fin.clear();
	fin.close();
	fout.close();

	return 0;
}

/**
输出结果:
	J:\VC++6.0 win7\C plusplus programs\lesson17\Review17\exampleNo3\Debug>
	exampleNo3 readfile.txt writefile.txt
	你好!欢迎来到C++学习课程!!
	我们来学习第十七章I/O流!
	读取完毕!
*/

/***********************************
	2017年12月26日12:59:45
	Athor:xiyuan255
	Course:C++
	Contain:pe17-4.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十七章的第四题练习题
		 【 参考 P792 】
*************************************/
// pe17-4.cpp -- using 命令行将键盘输入内容转换到文件中
#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char * argv[])
{
	using namespace std;

	if (argc != 4) {
	    cout << "输入参数有误!\n";
		exit(EXIT_FAILURE);
	}
	ifstream fin1(argv[1], ios_base::in);
	ifstream fin2(argv[2], ios_base::in);
	ofstream fout(argv[3], ios_base::out);

	if (!(fin1.is_open()||fin2.is_open()||fout.is_open())) {
		cout << "文件打开失败!\n";
		exit(EXIT_FAILURE);
	}
	string str1, str2;
	while ((!fin1.eof() && !fin2.eof()) 
		    && getline(fin1, str1) && getline(fin2, str2)) {  
		cout << str1 + " " + str2 << endl;
		fout << str1 + " " + str2 << endl;
	}
    while (!fin1.eof() && getline(fin1, str1)) {  
		cout << str1 << endl;
		fout << str1 << endl;
	}
	while (!fin2.eof() && getline(fin2, str2)) { 
		cout << str2 << endl;
		fout << str2 << endl;
	}

	if(fin1.eof() && fin2.eof())
		cout << "读取完毕!\n";
	else if (fin1.fail()||fin2.fail()) 
		cout << "读取异常!\n";
	else if (fin1.bad()||fin2.bad()) 
		cout << "硬件故障!\n";

	fin1.clear();
	fin2.clear();
	fin1.close();
	fin2.close();
	fout.close();

	return 0;
}

/**
输出结果:
	J:\VC++6.0 win7\C plusplus programs\lesson17\Review17\exampleNo4\Debug>
	exampleNo4 readfile1.txt readfile2.txt writefile.txt
	eggs kites donuts zero lassitude
	balloons hammers finance drama
	stones
	读取完毕!
*/

/***********************************
	2017年12月26日13:36:47
	Athor:xiyuan255
	Course:C++
	Contain:pe17-5.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十六章的第五题练习题
		 【 参考 P792 】
*************************************/
// pe16-8.cpp -- using
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <set>
#include <algorithm>

void show(const std::string & str)
{
	std::cout << str << " ";
}

int main()
{
	std::list<std::string> Mat; // 创建一个list容器(内核是双向链表)
	std::list<std::string> Pat;

	std::ifstream fin1("mat.dat"); 
	std::ifstream fin2("pat.dat");
	std::ofstream fout("matnpat.dat");

	if (!(fin1.is_open() && fin2.is_open())) {
		std::cout << "mat.dat or pat.dat open failure!\n";
		exit(EXIT_FAILURE);
	}
	
	std::string temp;
	std::cout << "Mat friend name from mat.dat: \n";
	while (getline(fin1, temp) && temp != "quit") {
		Mat.push_back(temp);
	}
	if(fin1.eof())
		std::cout << "mat.dat读取完毕!\n";
	else if (fin1.fail()) 
		std::cout << "mat.dat读取异常!\n";
	else if (fin1.bad()) 
		std::cout << "硬件故障!\n";

	Mat.sort();

	std::cout << "Pat friend name from pat.dat: \n";
	while (getline(fin2, temp) && temp != "quit") {
		Pat.push_back(temp);
	}
	if(fin2.eof())
		std::cout << "pat.dat读取完毕!\n";
	else if (fin2.fail()) 
		std::cout << "pat.dat读取异常!\n";
	else if (fin2.bad()) 
		std::cout << "硬件故障!\n";

	Pat.sort();

	std::cout << "Mat friend have: \n";
	for_each(Mat.begin(), Mat.end(), show);
	std::cout << std::endl;

	std::cout << "Pat friend have: \n";
	for_each(Pat.begin(), Pat.end(), show);
	std::cout << std::endl;

	// 方法一:
#if 0
	std::set<std::string> Merge;
	std::list<std::string>::iterator it;
	for (it = Mat.begin(); it != Mat.end(); it++)
		Merge.insert(*it);
	for (it = Pat.begin(); it != Pat.end(); it++)
		Merge.insert(*it);
#endif

	// 方法二:
	std::list<std::string> Merge;
	Merge = Mat;
	Merge.merge(Pat); // 将Mat和Pat合并
	Merge.unique();

	std::cout << "Merge friend have: \n";
	for_each(Merge.begin(), Merge.end(), show);
	std::cout << std::endl;

	// write to file 
	std::list<std::string>::iterator it;
	for (it = Merge.begin(); it != Merge.end(); it++)
		fout << (*it) << std::endl;

	fin1.clear();
	fin2.clear();
	fin1.close();
	fin2.close();
	fout.close();

	return 0;
}

/**
输出结果:
	Mat friend name from mat.dat:
	mat.dat读取完毕!
	Pat friend name from pat.dat:
	pat.dat读取完毕!
	Mat friend have:
	lishi wangwu xiaoming zhangsan zhaoliu
	Pat friend have:
	lilei lishi tianmo xiaohua xiaoqing zhaoliu
	Merge friend have:
	lilei lishi tianmo wangwu xiaohua xiaoming xiaoqing zhangsan zhaoliu
*/

// matnpat.dat
lilei
lishi
tianmo
wangwu
xiaohua
xiaoming
xiaoqing
zhangsan
zhaoliu

// mat.dat
mat.datzhangsan
lishi
wangwu
zhaoliu
xiaoming

// pat.dat
lishi
xiaohua
lilei
zhaoliu
tianmo
xiaoqing

// emp2.h -- header file for abstr_emp class and children
#ifndef __EMP2_H__
#define __EMP2_H__

#include <iostream>
#include <fstream>
#include <string>

enum classkind { EMPLOYEE, MANAGER, FINK, HIGHFINK }; // in class header

/* 该类包含纯虚函数成员(即virtual ~Abstr_Emp() = 0;),
 * 则该类是抽象类,不能直接生成对象 */
class Abstr_Emp 
{
private:
	std::string fname;   // abstr_emp's first name
	std::string lname;   // abstr_emp's last name
	std::string job;
public:
	Abstr_Emp();
	Abstr_Emp(const std::string & fn, const std::string & ln,
			const std::string & j);
	virtual void showAll() const;  // labels and ahows all data
	virtual void setAll();         // prompts user for values
	friend std::ostream & 
		operator<<(std::ostream & os, const Abstr_Emp & e);
	// just display first and last name
	virtual ~Abstr_Emp() = 0;      // virtual base class
	virtual void writeAll(std::ofstream & of);
};

class Employee : public Abstr_Emp
{
public:
	Employee();
	Employee(const std::string & fn, const std::string & ln,
			const std::string & j);
	virtual void showAll() const;
	virtual void setAll();
	virtual void writeAll(std::ofstream & of);
};

// Abstr_Emp是Manager和Fink以及HighFink类的虚基类,
// 因为他们两使用了虚继承,即关键字 : virtual public
// 所以派生类HighFink只包含一份虚基类Abstr_Emp对象的内容
class Manager : virtual public Employee  
{
private:
	int inchargeof;    // number of Abstr_Emp managed
protected:
	int inChargeOf() const { return inchargeof; }  // output
	int & inChargeOf() { return inchargeof; }      // input
public:
	Manager();
	Manager(const std::string & fn, const std::string & ln,
			const std::string & j, int ico = 0);
	Manager(const Employee & e, int ico);
	Manager(const Manager & m);
	virtual void data() const;
	virtual void setData();
	virtual void showAll() const;
	virtual void setAll();
	virtual void writeData(std::ofstream & of);
	virtual void writeAll(std::ofstream & of);
};

class Fink : virtual public Employee
{
private:
	std::string reportsto;    // to whom fink reports
protected:
	const std::string reportsTo() const { return reportsto; }
	std::string & reportsTo() { return reportsto; }
public:
	Fink();
	Fink(const std::string & fn, const std::string & ln,
			const std::string & j, const std::string & rpo);
	Fink(const Employee & e, const std::string & rpo);
	Fink(const Fink & f);
	virtual void data() const;
	virtual void setData();
	virtual void showAll() const;
	virtual void setAll();
	virtual void writeData(std::ofstream & of);
	virtual void writeAll(std::ofstream & of);
};

class HighFink : public Manager, public Fink  // management fink
{
public:
	HighFink();
	HighFink(const std::string & fn, const std::string & ln,
			const std::string & j, const std::string & rpo,
			int ico);
	HighFink(const Employee & e, const std::string & rpo, int ico);
	HighFink(const Fink & f, int ico);
	HighFink(const Manager & m, const std::string & rpo);
	HighFink(const HighFink & h);
	virtual void showAll() const;
	virtual void setAll();
	virtual void writeAll(std::ofstream & of);
};

#endif /* __EMP2_H__ */

// emp.cpp -- class menthods definition
#include "emp2.h"

// class Abstr_Emp methods
Abstr_Emp::Abstr_Emp()
{
	fname = "none";
	lname = "none";
	job = "none";
}

Abstr_Emp::Abstr_Emp(const std::string & fn, 
				const std::string & ln,
				const std::string & j)
{
	fname = fn;
	lname = ln;
	job = j;
}

Abstr_Emp::~Abstr_Emp()
{ }

void Abstr_Emp::showAll() const
{
	std::cout << "FirstName: " << fname << std::endl;
	std::cout << "LastName: " << lname << std::endl;
	std::cout << "JobName: " << job << std::endl;
}

void Abstr_Emp::setAll()
{
	std::cout << "Enter first name: ";
	getline(std::cin, fname);
	std::cout << "Enter last name: ";
	getline(std::cin, lname);
	std::cout << "Enter job name: ";
	getline(std::cin, job);
}

std::ostream & operator<<(std::ostream & os, const Abstr_Emp & e)
{
	os << e.fname << ", " << e.lname << ", " << e.job << " ";
	return os;
}

void Abstr_Emp::writeAll(std::ofstream & of)
{
	of << "First name: ";
	of << fname << std::endl;
	of << "Last name: ";
	of << lname << std::endl;
	of << "Job name: ";
	of << job << std::endl;
}

// class Employee methods
Employee::Employee() : Abstr_Emp()
{ }

Employee::Employee(const std::string & fn, 
	const std::string & ln, const std::string & j)
	: Abstr_Emp(fn, ln, j)
{ }

void Employee::showAll() const
{
	Abstr_Emp::showAll();
}

void Employee::setAll()
{
	Abstr_Emp::setAll();
}

void Employee::writeAll(std::ofstream & of)
{
	Abstr_Emp::writeAll(of);
}

// class Manager methods
Manager::Manager() : Employee(), inchargeof(0)
{ }

Manager::Manager(const std::string & fn, 
	const std::string & ln, const std::string & j, int ico)
	: Employee(fn, ln, j), inchargeof(ico)
{ }

Manager::Manager(const Employee & e, 
	int ico) : Employee(e), inchargeof(ico)
{ }

Manager::Manager(const Manager & m) : Employee(m)
{
	inchargeof = m.inchargeof;
}

void Manager::data() const
{
	std::cout << "InChargeOf: " << inchargeof << std::endl;
}

void Manager::showAll() const
{
	Employee::showAll();
	data();
}

void Manager::setData()
{
	std::cout << "Enter InChargeOf: ";
	std::cin >> inchargeof;
	while (std::cin.get() != '\n')
		continue;
}

void Manager::setAll()
{
	Employee::setAll();
	setData();
}

void Manager::writeData(std::ofstream & of)
{
	of << "InChargeOf: ";
	of << inchargeof << std::endl;
}

void Manager::writeAll(std::ofstream & of)
{
	Employee::writeAll(of);
	writeData(of);
}

// class Fink methods
Fink::Fink() : Employee(), reportsto("none")
{ }

Fink::Fink(const std::string & fn, const std::string & ln,
		const std::string & j, const std::string & rpo)
		: Employee(fn, ln, j), reportsto(rpo)
{
}

Fink::Fink(const Employee & e, const std::string & rpo)
	: Employee(e), reportsto(rpo)
{
}

Fink::Fink(const Fink & f) : Employee(f)
{
	reportsto = f.reportsto;
}

void Fink::data() const
{
	std::cout << "ReportsTo: " << reportsto << std::endl;
}

void Fink::showAll() const
{
	Employee::showAll();
	data();
}

void Fink::setData()
{
	std::cout << "Enter ReportsTo: ";
	getline(std::cin, reportsto);
}

void Fink::setAll()
{
	Employee::setAll();
	setData();
}

void Fink::writeData(std::ofstream & of)
{
	of << "ReportsTo: ";
	of << reportsto << std::endl;
}

void Fink::writeAll(std::ofstream & of)
{
	Employee::writeAll(of);
	writeData(of);
}

// class Fink methods
HighFink::HighFink() : Employee(), Manager(), Fink()
{ }

HighFink::HighFink(const std::string & fn, const std::string & ln,
			const std::string & j, const std::string & rpo,
			int ico) : Employee(fn, ln, j), Fink(fn, ln, j, rpo),
			Manager(fn, ln, j, ico)
{ }

HighFink::HighFink(const Employee & e, const std::string & rpo, 
	int ico) : Employee(e), Fink(e, rpo)
{ }

HighFink::HighFink(const Fink & f, int ico) 
	: Employee(f), Fink(f), Manager((f), ico)  // (Abstr_Emp &)
{ }

HighFink::HighFink(const Manager & m, const std::string & rpo)
	: Employee(m), Manager(m), Fink(m, rpo)
{ }

HighFink::HighFink(const HighFink & h) : Employee(h),
			Manager(h), Fink(h)
{ }

void HighFink::showAll() const
{
	Employee::showAll();
	Manager::data();
	Fink::data();
}

void HighFink::setAll()
{
	Employee::setAll();
	Manager::setData();
	Fink::setData();
}

void HighFink::writeAll(std::ofstream & of)
{
	Employee::writeAll(of);
	Manager::writeData(of);
	Fink::writeData(of);
}

/***********************************
	2017年12月26日15:42:56
	Athor:xiyuan255
	Course:C++
	Contain:pe17-6.cpp
			 emp2.h
		     emp2.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十七章的第六题练习题
		 【 参考 P793 】
*************************************/
// pe17-6.cpp -- using fstream and class
#include <iostream>
#include <fstream>
#include "emp2.h"

int main()
{
	using namespace std;

	/* 将文件模式设置为写入,且数据加入到文件尾部 */
	ofstream fout("savemessage.txt", ios_base::out | ios_base::app);
	if (!fout.is_open()) {
		cout << "savemessage文件打开失败!\n";
		exit(EXIT_FAILURE);
	}
	
#if 0 // 程序第一次运行代码
	cout << "请输入Employee对象的内容:\n";
	Employee emp;
	emp.setAll();
	cout << "请输入Manager对象的内容:\n";
	Manager man;
	man.setAll();
	cout << "请输入Fink对象的内容:\n";
	Fink fink;
	fink.setAll();
	cout << "请输入HighFink对象的内容:\n";
	HighFink hf;
	hf.setAll();

	// 将数据发送给在显示屏
	emp.showAll();
	man.showAll();
	fink.showAll();
	hf.showAll();

	// 将数据发送给savemessage文件
	emp.writeAll(fout);
	man.writeAll(fout);
	fink.writeAll(fout);
	hf.writeAll(fout);
#endif
	/* 将文件模式设置为读取 */
	ifstream fin("savemessage.txt", ios_base::in);
	string temp;
	while (getline(fin, temp) && temp.size() > 0) {
		cout << temp << endl;
	}
	fin.clear();
	fin.close();

	const int MAX = 10;  // no more than 10 objects

	Employee * pc[MAX];

	cout << "输入创建的对象类型(会添加到文件中):\n"
		 << "0: Employee  1: Manager 2: Fink "
		 << "3: HighFink  4: exit \n";
	char ch;
	int classtype;
	int index = 0;
	/* newline separates int from data : 必须要加这条语句'.get(ch)'
	 * 因为当我们如输入0回车,则会将换行符留在输入队列中,所以对象
	 * 的第一个first name就会获取到换行符,直接结束输入 */
	while ((cin >> classtype).get(ch) && index < MAX) { 
		if (classtype > HIGHFINK) 
			break;
		switch (classtype) {
			case EMPLOYEE :
				pc[index] = new Employee;
				break;
			case MANAGER :
				pc[index] = new Manager;
				break;
			case FINK :
				pc[index] = new Fink;
				break;
			case HIGHFINK :
				pc[index] = new HighFink;
				break;
		}
		pc[index++]->setAll();
		cout << "输入创建的对象类型(会添加到文件中):\n"
		     << "0: Employee  1: Manager 2: Fink "
		     << "3: HighFink  4: exit \n";
	}
	// 将数据写入文件
	for (int i = 0; i < index; i++)
		pc[i]->writeAll(fout); // fout ofstream connected to output file

	// 显示输入的信息
	for (int i = 0; i < index; i++)
		pc[i]->showAll(); 
	
	fout.close();

	return 0;
}

/**
输出结果:
	First name: Trip
	Last name: Harris
	Job name: Thumper
	First name: Amophia
	Last name: Spindragon
	Job name: Nuancer
	InChargeOf: 5
	First name: Matt
	Last name: Oggs
	Job name: Oiler
	ReportsTo: Juno Barr
	First name: Amophia
	Last name: Spindragon
	Job name: Nuancer
	InChargeOf: 5
	ReportsTo: Curly Kew
	输入创建的对象类型(会添加到文件中):
	0: Employee  1: Manager 2: Fink 3: HighFink  4: exit
	0
	Enter first name: zhang
	Enter last name: san
	Enter job name: chengxuyuan
	输入创建的对象类型(会添加到文件中):
	0: Employee  1: Manager 2: Fink 3: HighFink  4: exit
	2
	Enter first name: li
	Enter last name: shi
	Enter job name: chushi
	Enter ReportsTo: hengxian
	输入创建的对象类型(会添加到文件中):
	0: Employee  1: Manager 2: Fink 3: HighFink  4: exit
	2
	Enter first name: wangwu
	Enter last name: ming
	Enter job name: wulaio
	Enter ReportsTo: bukaixin
	输入创建的对象类型(会添加到文件中):
	0: Employee  1: Manager 2: Fink 3: HighFink  4: exit
	3
	Enter first name: zhao
	Enter last name: liu
	Enter job name: laoshi
	Enter InChargeOf: 8
	Enter ReportsTo: xingfen
	输入创建的对象类型(会添加到文件中):
	0: Employee  1: Manager 2: Fink 3: HighFink  4: exit
	1
	Enter first name: xiao
	Enter last name: ming
	Enter job name: xuesheng
	Enter InChargeOf: 6
	输入创建的对象类型(会添加到文件中):
	0: Employee  1: Manager 2: Fink 3: HighFink  4: exit
	4
	FirstName: zhang
	LastName: san
	JobName: chengxuyuan
	FirstName: li
	LastName: shi
	JobName: chushi
	ReportsTo: hengxian
	FirstName: wangwu
	LastName: ming
	JobName: wulaio
	ReportsTo: bukaixin
	FirstName: zhao
	LastName: liu
	JobName: laoshi
	InChargeOf: 8
	ReportsTo: xingfen
	FirstName: xiao
	LastName: ming
	JobName: xuesheng
	InChargeOf: 6
*/

// savemessage.txt
First name: Trip
Last name: Harris
Job name: Thumper
First name: Amophia
Last name: Spindragon
Job name: Nuancer
InChargeOf: 5
First name: Matt
Last name: Oggs
Job name: Oiler
ReportsTo: Juno Barr
First name: Amophia
Last name: Spindragon
Job name: Nuancer
InChargeOf: 5
ReportsTo: Curly Kew
First name: zhang
Last name: san
Job name: chengxuyuan

First name: li
Last name: shi
Job name: chushi

ReportsTo: hengxian
First name: wangwu
Last name: ming
Job name: wulaio

ReportsTo: bukaixin
First name: zhao
Last name: liu
Job name: laoshi

InChargeOf: 8
ReportsTo: xingfen
First name: xiao
Last name: ming
Job name: xuesheng

InChargeOf: 6

/***********************************
	2017年12月26日17:05:51
	Athor:xiyuan255
	Course:C++
	Contain:pe17-7.cpp
	Reference: C++ Primer plus
	说明:C++ Primer plus第十七章的第七题练习题
		 【 参考 P794 】
*************************************/
// pe17-7.cpp -- using vector and fstream
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>

class Store
{
private:
	std::ostream & os;
public:
	Store(std::ostream & fout) : os(fout) { }
	void operator()(const std::string & str) {
		size_t len = str.size();
		/* typedef unsigned int size_t; */ // 之所以要
		// 使用size_t而不使用int,不同平台可能不一样,
		// 这样写是为了移植性好
		os.write((char *)&len, sizeof(std::size_t));
		os.write(str.data(), len); // data()成员函数返回
		         // 一个指针,该指针指向一个其中存储了字符串
		         // 的字符数组。它与c_str()区别是,它不会在该
		         // 数组末尾加上一个空字符,而c_str()方法会。
	}
};

void ShowStr(const std::string & str);
void GetStrs(std::ifstream & fin, 
	     std::vector<std::string> & vistr);

int main()
{
	using namespace std;
	vector<string> vostr; 
	string temp;

// acquire strings
	cout << "Enter strings (empty line to quit):\n";
	while (getline(cin, temp) && temp.size() > 0)
		vostr.push_back(temp);
	cout << "Here is your input.\n";
	for_each(vostr.begin(), vostr.end(), ShowStr);

// store in a file
	ofstream fout("strings.dat", ios_base::out | ios_base::binary);
	for_each(vostr.begin(), vostr.end(), Store(fout)); // for_each
    // 会自动调用Store(fout)(std::string & str)函数,过程如下:
	// Store(fout)则调用构造函数Store(std::ostream & fout)
	// 创建对象,将fout对象赋给os,因为是引用,所以指向相同的
	// 内存区域。然后for_each通过迭代器每次从容器vostr拿出一个
	// string对象,然后调用operator()(const std::string & str)
	// 函数进行将数据写入文件。

	fout.close();

// recover file contents
	vector<string> vistr;
	ifstream fin("strings.dat", ios_base::in | ios_base::binary);
	if (!fin.is_open()) {
		cerr << "Could not open file for 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;
}

/**
输出结果:
	Enter strings (empty line to quit):
	xiao ming
	xiao hua
	zhang san li shi
	wang wu zhao liu

	Here is your input.
	xiao ming
	xiao hua
	zhang san li shi
	wang wu zhao liu

	Here are the strings read from the file:
	xiao ming
	xiao hua
	zhang san li shi
	wang wu zhao liu
*/

void ShowStr(const std::string & str)
{
	std::cout << str << std::endl;
}

void GetStrs(std::ifstream & fin, std::vector<std::string> & vistr)
{
	size_t len;
	std::string temp;
	while (fin.read((char *)&len, sizeof(size_t))) {
		char * str = new char[len + 1];
		fin.read(str, len);
		str[len] = '\0';
		vistr.push_back(str);
		delete[] str;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值