C++程序设计原理与实践 习题答案 第十一章 第11章习题答案

11.1

#include"../../std_lib_facilities.h"

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	string ofname;	//新的文件名
	cout << "Enter a output file name\n";
	cin >> ofname;
	ofstream ofs{ ofname };
	if(!ofs)
		error("can't open file ", ofname);
	
	//把输入文件中的字母转换为小写字母,输出到新文件中
	for (char ch{ 0 }; ifs.get(ch);)
	{
		ch = tolower(ch);
		ofs << ch;
	}
	
	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.2

#include"../../std_lib_facilities.h"

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	string word;	
	cout << "Enter a word\n";
	cin >> word;
	
	string line;
	int line_num{ 1 };
	while (getline(ifs, line))
	{
		/* string的成员函数 find() 返回 string::size_type 类型的值。
			以下标形式标记查找匹配所发生的位置;
			或者返回一个名为 string::npos 的特殊值(它说明查找没有匹配的)。
			string 类将 npos 定义为保证大于任何有效下标的值。
		 */
		if (line.find(word) != string::npos)		
			cout << line_num << ' ' << line << '\n';
		line_num++;
	}

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.3

#include"../../std_lib_facilities.h"

bool is_vowel(char ch)
{
	const string vowels{ "AaEeIiOoUu" };
	for (char v : vowels)
		if (ch == v)
			return true;
	return false;
}

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	string ofname;	
	cout << "Enter a output file name\n";
	cin >> ofname;
	ofstream ofs{ ofname };
	if (!ofs)
		error("can't open file ", ofname);
	
	for (char ch{ 0 }; ifs.get(ch);)
		if (!is_vowel(ch))
			ofs << ch;

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.4

#include"../../std_lib_facilities.h"

enum class Base {
	oct, dec, hex
};

const vector<string>bs{
	"octal", "decimal", "hexadecimal" };

struct Integer {
	int n;
	Base b;
};



void write(const Integer& i)
{
	cout << showbase;
	switch (i.b)
	{
	case Base::oct:
		cout << oct << setw(10) << i.n << "\toctal\t\tconverts to\t";
		break;
	case Base::dec:
		cout << dec << setw(10) << i.n << "\tdecimal\t\tconverts to\t";
		break;
	case Base::hex:
		cout << hex << setw(10) << i.n << "\thexadecimal\tconverts to\t";
		break;
	}
	cout << dec << setw(8) << i.n << "\tdecimal\n";
}

int main()
try
{
	cout << "How many integer do you want to enter?\n";
	int n;
	while (cin >> n)
		if (n <= 0)
			cout << "Try again! How many integer do you want to enter?\n";
		else
			break;

	cout << "Now enter" << n <<" integer, you can type in octal with 0 prefix, \
			decimal with no prefix, hexadecimal with 0x or 0X prefix\n";

	vector<Integer>vi;
	char ch;
	int i;
	Base b;
	while (n--)
	{
		while (cin.get(ch) && !isdigit(ch))
			continue;
		if (ch == '0')
		{
			char ch2;
			if (cin.get(ch2) && (ch2 == 'x' || ch2 == 'X'))	//hex
			{
				cin >> hex >> i;
				b = Base::hex;
			}
			else if (isdigit(ch2))	//oct
			{
				cin.putback(ch2);
				cin >> oct >> i;
				b = Base::oct;
			}
			else
			{
				// integer 0
				cin.putback(ch2);
				i = 0;
				b = Base::dec;
			}
		}
		else
		{
			cin.unget();
			cin >> dec >> i;
			b = Base::dec;
		}
		vi.push_back(Integer{ i,b });
	}

	for (const Integer& i : vi)
		write(i);

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.5

#include"../../std_lib_facilities.h"

int main()
try
{
	cout << "Enter a string and I will classify its characters, enter ctrl + z  in newline with no other character to quit\n";
	string s;
	while (cin >> s)
	{
		cout << "character\t" << setw(8) << "type\n";
		for (char ch : s)
		{
			cout << setw(5) << ch << "\t\t";	
			if (isprint(ch))
			{
				cout << setw(8) << "Print";
				if (isgraph(ch))
				{
					cout << setw(8) << "Graph";
					if(ispunct(ch))
						cout << setw(8) << "Punct";
					else if (isalnum(ch))
					{
						cout << setw(16) << "Alpha & Number";
						if (isdigit(ch))
							cout << setw(8) << "Digit";
						if (isxdigit(ch))
							cout << setw(8) << "Xdigit";
						if (isalpha(ch))
						{
							cout << setw(8) << "Alpha";
							if(isupper(ch))
								cout << setw(8) << "Upper";
							else
								cout << setw(8) << "Lower";
						}
					}
				}
				else if (isspace(ch))
					cout << setw(8) << "Space";
			}
			else if (iscntrl(ch))
			{
				cout << setw(8) << "Control";
			}
			else
				cout << "No Type";
			cout << '\n';
		}
		cout << "Try again\n";
	}


	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.6

#include"../../std_lib_facilities.h"

class Punct {
public:
	Punct(const string& s) 
		: punct{ s } { }
	
	void begin_punct(char c);
	void end_punct(char c);
	void add_punct(char c)
	{
		punct += c;
	}
	bool is_punct_white(char c);
	bool is_begin(char c)
	{
		return c == begin;
	}
	bool is_end(char c)
	{
		return c == end;
	}

private:
	string punct;
	
	//开始与结束符号之间的punct不转化为空白符
	char begin;		
	char end;
};

bool Punct::is_punct_white(char c)
{
	for (char ch : punct)
		if (ch == c)
			return true;
	return false;
}

void Punct::begin_punct(char c)
{
	if (is_punct_white(c))
		error("can't set begin punct");
	begin = c;
}
void Punct::end_punct(char c)
{
	if (is_punct_white(c))
		error("can't set end punct");
	end = c;
}

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	//把输入文件中的标点转换为空白符
	//标点为 . , ? - '
	//不修改双引号之间的标点
	//本程序默认输出为cout,也可以写入文件
	Punct puc{".;,?-'"};
	puc.begin_punct('"');
	puc.end_punct('"');
	string line;
	bool flag{ false };	// true == 在双引号内,false == 不在双引号内
	while (getline(ifs, line))
	{
		for (char& c : line)
			if (flag)
			{
				if (puc.is_end(c))
					flag = false;
			}
			else
			{
				if (puc.is_punct_white(c))
					c = ' ';
				else if (puc.is_begin(c))
					flag = true;
			}
		cout << line << endl;
	}

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.7

#include"../../std_lib_facilities.h"

class Punct {
public:
	Punct(const string& s)
		: punct{ s } { }

	void begin_punct(char c);
	void end_punct(char c);
	void add_punct(char c)
	{
		punct += c;
	}
	bool is_punct_white(char c);
	bool is_begin(char c)
	{
		return c == begin;
	}
	bool is_end(char c)
	{
		return c == end;
	}

private:
	string punct;

	//开始与结束符号之间的punct不转化为空白符
	char begin;
	char end;
};

bool Punct::is_punct_white(char c)
{
	for (char ch : punct)
		if (ch == c)
			return true;
	return false;
}

void Punct::begin_punct(char c)
{
	if (is_punct_white(c))
		error("can't set begin punct");
	begin = c;
}
void Punct::end_punct(char c)
{
	if (is_punct_white(c))
		error("can't set end punct");
	end = c;
}

struct SpokenWritten {
	string spk;
	string wrt;
};
vector<SpokenWritten>vsw{
	SpokenWritten{"don't", "do not"},
	SpokenWritten{"can't", "can not"},
	SpokenWritten{"isn't", "is not"},
	SpokenWritten{"aren't", "are not"}
};

#define NotFound -1

int find_vsw_index(const string& sp)
{
	for (int i = 0; i < vsw.size(); i++)
		if (vsw[i].spk == sp)
			return i;
	return NotFound;
}

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	//把输入文件中的标点转换为空白符
	//标点为 . , ? - '
	//单词内的连字符保持不变
	//don't转换为do not, can't转换为can not,isn't转换为is not,aren't转换为are not,其他懒得实现了
	//不修改双引号之间的标点
	//本程序默认输出为cout,也可以写入文件
	Punct puc{ ".;,?-'" };
	puc.begin_punct('"');
	puc.end_punct('"');
	string line, word;
	char c;
	bool flag{ false };	// true == 在双引号内,false == 不在双引号内
	ostringstream oss;
	
	while (getline(ifs, line))
	{
		istringstream iss{ line };
		while (iss.get(c))
		{
			if (flag)	//在双引号内,不处理
			{
				if (puc.is_end(c))
					flag = false;
				oss << c;
			}
			else
			{
				if (isspace(c))
					oss << c;
				else if (puc.is_begin(c))
				{
					flag = true;
					oss << c;
				}
				else
				{
					iss.unget();
					iss >> word;
					for (char& ch : word)
						ch = tolower(ch);
					int index;
					if ((index = find_vsw_index(word)) != NotFound)
						oss << vsw[index].wrt;
					else 
						for (int i = 0; i < word.size(); i++)
						{
							c = word[i];
							if (puc.is_punct_white(c))
							{
								if (c != '-')
									c = ' ';
								else if (i == 0 || i == word.size() - 1)
									c = ' ';
							}
							c = tolower(c);
							oss << c;
						}
				}
			}
		}
		oss << '\n';
	}
	cout << oss.str();
	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.8

#include"../../std_lib_facilities.h"

class Punct {
public:
	Punct(const string& s)
		: punct{ s } { }

	void begin_punct(char c);
	void end_punct(char c);
	void add_punct(char c)
	{
		punct += c;
	}
	bool is_punct_white(char c);
	bool is_begin(char c)
	{
		return c == begin;
	}
	bool is_end(char c)
	{
		return c == end;
	}

private:
	string punct;

	//开始与结束符号之间的punct不转化为空白符
	char begin;
	char end;
};

bool Punct::is_punct_white(char c)
{
	for (char ch : punct)
		if (ch == c)
			return true;
	return false;
}

void Punct::begin_punct(char c)
{
	if (is_punct_white(c))
		error("can't set begin punct");
	begin = c;
}
void Punct::end_punct(char c)
{
	if (is_punct_white(c))
		error("can't set end punct");
	end = c;
}

struct SpokenWritten {
	string spk;
	string wrt;
};
vector<SpokenWritten>vsw{
	SpokenWritten{"don't", "do not"},
	SpokenWritten{"can't", "can not"},
	SpokenWritten{"isn't", "is not"},
	SpokenWritten{"aren't", "are not"}
};

#define NotFound -1

int find_vsw_index(const string& sp)
{
	for (int i = 0; i < vsw.size(); i++)
		if (vsw[i].spk == sp)
			return i;
	return NotFound;
}

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	//把输入文件中的标点转换为空白符
	//标点为 . , ? - '
	//单词内的连字符保持不变
	//don't转换为do not, can't转换为can not,isn't转换为is not,aren't转换为are not,其他懒得实现了
	//不修改双引号之间的标点
	//本程序默认输出为cout,也可以写入文件
	Punct puc{ ".;,?-'" };
	puc.begin_punct('"');
	puc.end_punct('"');
	string line, word;
	char c;
	bool flag{ false };	// true == 在双引号内,false == 不在双引号内
	istringstream iss;
	ostringstream oss;

	while (getline(ifs, line))
	{
		iss.clear();
		iss.str(line);
		while (iss.get(c))
		{
			if (flag)	//在双引号内,不处理
			{
				if (puc.is_end(c))
					flag = false;
				oss << c;
			}
			else
			{
				if (isspace(c))
					oss << c;
				else if (puc.is_begin(c))
				{
					flag = true;
					oss << c;
				}
				else
				{
					iss.unget();
					iss >> word;
					for (char& ch : word)
						ch = tolower(ch);
					int index;
					if ((index = find_vsw_index(word)) != NotFound)
						oss << vsw[index].wrt;
					else
						for (int i = 0; i < word.size(); i++)
						{
							c = word[i];
							if (puc.is_punct_white(c))
							{
								if (c != '-')
									c = ' ';
								else if (i == 0 || i == word.size() - 1)
									c = ' ';
							}
							c = tolower(c);
							oss << c;
						}
				}
			}
		}
		oss << '\n';
	}
	iss.clear();
	iss.str(oss.str());
	//设置字典
	vector<string>dic;
	for (string s; iss >> s;)
		dic.push_back(s);
	//字典排序
	sort(dic.begin(), dic.end());
	//输出字典
	for (const string& s : dic)
		cout << s << endl;

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.9

#include"../../std_lib_facilities.h"

void txt2bin(const string& ifn, const string& ofn)
{
	ifstream ifs{ ifn };
	//ifstream ifs{ ifn, ios_base::binary };
	if (!ifs)
		error("can't open file ", ifn);
	ofstream ofs{ ofn, ios_base::binary };
	if (!ofs)
		error("can't open file ", ofn);
	
	//从文本文件读入字符并以字节形式写入二进制文件
	for (char c; ifs.get(c);)
		ofs.write(as_bytes(c), sizeof(char));
	/*for (int x; ifs.read(as_bytes(x), sizeof(int)); )		//如果都以binary形式打开文件,则要用这种方法
		ofs.write(as_bytes(x), sizeof(int));*/
}

void bin2txt(const string& ifn, const string& ofn)
{
	ifstream ifs{ ifn, ios_base::binary };
	if (!ifs)
		error("can't open file ", ifn);
	ofstream ofs{ ofn };
	//ofstream ofs{ ofn, ios_base::binary };
	if (!ofs)
		error("can't open file ", ofn);

	//从二进制文件读入字节,以字符形式存入文本文件
	for (char c; ifs.read(as_bytes(c), sizeof(char));)
		ofs << c;
	/*for (int x; ifs.read(as_bytes(x), sizeof(int)); )		//如果都以binary形式打开文件,则要用这种方法
		ofs.write(as_bytes(x), sizeof(int));*/
}

int main()
try
{
	string ifn_txt;
	cout << "Enter a input text file name\n";
	cin >> ifn_txt;
	
	string ofn_bin;
	cout << "Enter a output bin file name\n";
	cin >> ofn_bin;

	txt2bin(ifn_txt, ofn_bin);

	string ofn_txt;	
	cout << "Enter a output file name\n";
	cin >> ofn_txt;
	
	bin2txt(ofn_bin, ofn_txt);

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.10

#include"../../std_lib_facilities.h"

vector<string>split(const string& s)
{
	vector<string>vs;
	istringstream iss{ s };
	for (string buf; iss >> buf; )
		vs.push_back(buf);
	return vs;
}

int main()
try
{
	cout << "Enter a line:\n";
	string line;
	while (getline(cin, line))
	{
		vector<string>ln = split(line);
		cout << "Words in line:\n";
		for (string s : ln)
			cout << s << ' ';
		cout << '\n';
		cout << "Enter another line : \n";
	}

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.11

#include"../../std_lib_facilities.h"

bool is_whitespace(const char c, const string& w)
{
	for (char ch : w)
		if (ch == c)
			return true;
	return false;
}

vector<string>split(const string& s, const string& w)
//将s中以空白符以及w中的字符分隔的子字符串存入向量
{
	vector<string>vs;
	istringstream iss{ s };
	string ts;
	for (char c; iss.get(c); ts += c)
		if (is_whitespace(c, w))
			c = ' ';
	iss.clear();	//必须得把iss状态清除,因为之前的读取,iss.eof()是置位的
	iss.str(ts);
	for (string buf; iss >> buf; )
		vs.push_back(buf);
	return vs;
}

int main()
try
{
	cout << "Enter seperate characters in string:\n";
	string white;
	getline(cin, white);

	cout << "Enter a line:\n";
	string line;
	while (getline(cin, line))
	{
		vector<string>ln = split(line, white);
		cout << "Words in line:\n";
		for (string s : ln)
			cout << s << ' ';
		cout << '\n';
		cout << "Enter another line : \n";
	}

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.12

#include"../../std_lib_facilities.h"

void reverse(string& is)
{
	char temp;
	for (int i = 0, j = is.size() - 1; i < j; i++, j--)
	{
		temp = is[i];
		is[i] = is[j];
		is[j] = temp;
	}
}

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	string ofname = "rev" + ifname;
	ofstream ofs{ ofname };
	if(!ofs)
		error("can't open file ", ofname);
	
	//把输入文件的字符颠倒顺序,并输出到输出文件
	string is;
	for (char ch{ 0 }; ifs.get(ch); is += ch)
		;
	reverse(is);
	ofs << is;

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.13

#include"../../std_lib_facilities.h"

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	string ofname = "rev_" + ifname;
	ofstream ofs{ ofname };
	if (!ofs)
		error("can't open file ", ofname);

	//将输入文件中的单词(空白符间隔的字符串)顺序颠倒,并输出到输出文件
	vector<string>words;
	for (string word; ifs >> word; words.push_back(word))
		continue;
	for(int i = words.size() - 1; i >= 0; i--)
		ofs << words[i] << '\n';

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.14

懒得写了,这个和前面11.5很像,实在是太简单了。。

11.15

#include"../../std_lib_facilities.h"

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	string ofname = "scientific_" + ifname;
	ofstream ofs{ ofname };
	if (!ofs)
		error("can't open file ", ofname);

	//读取一个文件,文件格式是以空白符间隔的数值,
	//将这些数值输出到另一个文件,格式采用科学计数法
	//精度为8,每行4个域,每个域宽度为20个字符。
	vector<double>vd;
	for (double d; ifs >> d; vd.push_back(d))
		continue;
	ofs << scientific << setprecision(8);
	for (int i = 0; i < vd.size(); i++)
	{
		ofs << setw(20) << vd[i];
		if ((i + 1) % 4 == 0)	//每行4个域
			ofs << '\n';
	}
	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

11.16

#include"../../std_lib_facilities.h"

int main()
try
{
	string ifname;
	cout << "Enter a input file name\n";
	cin >> ifname;
	ifstream ifs{ ifname };
	if (!ifs)
		error("can't open file ", ifname);

	//读取一个空白符间隔的数值文件,按升序输出这些数值,每行一个值。
	//每个数值只输出一次,如果一个数值在原文件中多次出现,同时输出它出现的次数
	vector<double>vd;
	for (double d; ifs >> d; vd.push_back(d))
		continue;
	sort(vd);
	int cnt{ 0 };
	for (size_t i = 0; i < vd.size(); i++)
	{
		if (i == 0 || vd[i] != vd[i - 1])
		{
			if (cnt > 1)
				cout << '\t' << setw(4) << cnt << '\n';
			else if (cnt == 1)
				cout << '\n';
			cout << vd[i];
			cnt = 1;
		}
		else
			++cnt;
	}
	if (cnt > 1)
		cout << '\t' << setw(4) << cnt << '\n';
	else if (cnt == 1)
		cout << '\n';
	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << '\n';
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值