C++ Primer 第五版 课后章节练习答案 第八章

编译软件为 vs2015。

第八章

练习8.1:

编写函数,接受一个 istream& 参数,返回值类型也是 istream&。此函数必须从给定流中读取数据,直至遇到文件结束标识时停止。它读取的数据打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。

解答:

(注要求此函数从给定流中读取数据)

#include <iostream>
#include <string>
using namespace std;

istream &func(istream &input)
{
	string str;
	while (input >> str)
	{
		cout << str << endl;
	}
	input.clear();
	return input;
}

练习8.2:

测试函数,调用参数为 cin。

解答:

#include <iostream>
#include <string>
using namespace std;

istream &func(istream &input)
{
	string str;
	while (input >> str)
	{
		cout << str << endl;
	}
	input.clear();
	return input;
}

int main()
{
	istream &in = func(cin);
	cout << in.rdstate() << endl;
	system("pause");
	return 0;
}

练习8.3:

什么情况下,下面的 while 循环会终止?

while(cin>>i){ /*......*/ }

解答:

循环结束的条件:遇到 这三种情况 badbit(流已崩溃,系统级错误),failbit(IO 操作失败,可恢复错误),eofbit(到达文件结束符)。

练习8.4:

编写函数,以读模式打开一个文件,将其内容读入到一个 string 的 vector 中,将每一行作为一个独立的元素存在一个 vector 中。

解答:

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

using namespace std;

void ReadFile(const string &filename, vector<string> &vec)
{
	ifstream input(filename);
	if (input)  // 如果读取成功
	{
		string str;
		while (getline(input, str))
		{
			vec.push_back(str);
		}
	}
}

int main()
{
	vector<string> vec;
	ReadFile("D:\\string.txt", vec);
	cout << "file content: " << endl;
	for (auto &c : vec)
	{
		cout << c << endl;
	}
	system("pause");
	return 0;
}

练习8.5:

重写上面的程序,将每个单词作为一个独立的元素存储。

解答:

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

using namespace std;

void ReadFile(const string &filename, vector<string> &vec)
{
	ifstream input(filename);
	if (input)  // 如果读取成功
	{
		string str;
		while (input >> str)
		{
			vec.push_back(str);
		}
	}
}

int main()
{
	vector<string> vec;
	ReadFile("D:\\string.txt", vec);
	cout << "file content: " << endl;
	for (auto &c : vec)
	{
		cout << c << endl;
	}
	system("pause");
	return 0;
}

练习8.6:

重写 7.1.1 节的书店(第229页),从一个文件中读取交易记录。将文件名作为一个参数传递给 main (参见 6.2.5节,第 196 页)。

解答:

Sales_Data.h 文件如下:

#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <iostream>
#include <string>
using namespace std;
class Sales_data
{
public:
	string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
	double aver_price = 0.0;

	string isbn() const { return bookNo; };
	Sales_data &combine(const Sales_data &item);
};

istream &read(istream &is, Sales_data &item)
{
	double price = 0.0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price*item.units_sold;
	return is;
}

ostream &print(ostream &os, const Sales_data &item)
{
	os << item.bookNo << " " << item.units_sold << " " << item.revenue
		<< " " << item.revenue / item.units_sold;
	return os;
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;
	sum.combine(rhs);
	return sum;
}

Sales_data &Sales_data::combine(const Sales_data &item)
{
	units_sold += item.units_sold;
	revenue += item.revenue;
	aver_price = revenue / units_sold;
	return *this;
}

#endif  //Sales_Data_H

main.cpp 文件如下:

#include "Sales_Data.h"
#include <fstream>
using namespace std;

int main(int argc, char *argv[])  //argv[0]一般为一个空字符
{
	argv[1] = "D:\\Sales_Record.txt";
	ifstream input(argv[1]);

	Sales_data total;
	if (read(input, total))
	{
		Sales_data trans;
		while (read(input, trans))
		{
			if (total.isbn() == trans.isbn())
				//total.combine(trans);
				total = add(total, trans);
			else
			{
				print(cout, total);
				cout << endl;
				total = trans;
			}
		}
		print(cout, total);
		cout << endl;
	}
	else
	{
		cerr << "No data?!" << endl;
	}
	system("pause");
	return 0;
}

 Sales_Record.txt 文件如下:

运行结果:

练习8.7:

修改上一节的书店程序,将结果保存到一个文件中。将输出文件名作为第二个参数传递给 main 函数。

解答:

Sales_Data.h 文件同上,main.cpp 文件如下: 

#include "Sales_Data.h"
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
	argv[1] = "D:\\Sales_Record.txt";
	argv[2] = "D:\\Sales_Result.txt";
	ifstream input(argv[1]);
	ofstream output(argv[2]);

	Sales_data total;
	if (read(input, total))
	{
		Sales_data trans;
		while (read(input, trans))
		{
			if (total.isbn() == trans.isbn())
				//total.combine(trans);
				total = add(total, trans);
			else
			{
				print(output, total);
				cout << endl;
				total = trans;
			}
		}
		print(output, total);
		cout << endl;
	}
	else
	{
		cerr << "No data?!" << endl;
	}
	system("pause");
	return 0;
}

保存文件的内容如下: 

练习8.8:

修改上一题的程序,将结果追加到给定的文件末尾。对同一输出文件,运行程序至少两次,检验数据是否得以保留。

解答:

#include "Sales_Data.h"
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
	argv[1] = "D:\\Sales_Record.txt";
	argv[2] = "D:\\Sales_Result.txt";
	ifstream input(argv[1]);
	ofstream output(argv[2], ofstream::app);

	Sales_data total;
	if (read(input, total))
	{
		Sales_data trans;
		while (read(input, trans))
		{
			if (total.isbn() == trans.isbn())
				//total.combine(trans);
				total = add(total, trans);
			else
			{
				print(output, total);
				cout << endl;
				total = trans;
			}
		}
		print(output, total);
		cout << endl;
	}
	else
	{
		cerr << "No data?!" << endl;
	}
	system("pause");
	return 0;
}

 

可以看到,每运行一次程序,文件结果都会重新保存一次,且之前的结果也不会被丢弃。 

练习8.9:

使用你为 8.1.2 节(第 281 页)第一个练习所编写的函数打印一个 istringstream 对象的内容。

解答:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

istream &func(istream &input)
{
	string str;
	while (input >> str)
	{
		cout << str << endl;
	}
	input.clear();
	return input;
}

int main()
{
	istringstream istr("Hello world");
	func(istr);
	system("pause");
	return 0;
}

练习8.10:

编写程序,将来自一个文件中的行保存在一个 vector<string> 中。然后使用一个 istringstream 从 vector 中读取数据元素,每次读取一个单词。

解答:

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	argv[1] = "D:\\string.txt";
	ifstream input(argv[1]);
	vector<string> vec;
	string str;
	while (getline(input, str))
	{
		vec.push_back(str);
	}

	for (auto &c : vec)
	{
		istringstream output(c);
		string word;
		while (output >> word)
			cout << word << endl;
	}

	system("pause");
	return 0;
}

练习8.11:

本节的程序在外层 while 循环中定义了 istringstream 对象。如果 record 对象定义在循环之外,你需要对程序进行怎样的修改?重写程序,将 record 定义移到 while 之外,验证你设想的修改方法是否正确。

解答:

#include <string>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;

struct PersonInfo
{
	string name;
	vector<string> phones;

};

int main()
{
	string line, word;
	vector<PersonInfo> people;
	istringstream record;
	while (getline(cin, line))
	{
		PersonInfo info;
		record.clear();
		record.str(line);
		record >> info.name;
		while (record >> word)
		{
			info.phones.push_back(word);
			people.push_back(info);
		}
	}
	for (auto &c : people)
	{
		cout << c.name << endl;
		for (auto & p : c.phones)
		{
			cout << p << " " << endl;
		}
	}
	system("pause");
	return 0;
}

练习8.12:

我们为什么没有在 PersonInfo 中使用类初始化?

解答:

PersonInfo 在这里是一个聚合类,因此没有类内初始化和构造函数。

练习8.13:

重写本节的电话号码程序,从一个命名文件而非 cin 读取数据。

解答:

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;

struct PersonInfo
{
	string name;
	vector<string> phones;

};

int main()
{
	ifstream input("D:\\school use\\Vspractice\\pra8_13\\Phones.txt");

	string line, word;
	vector<PersonInfo> people;
	istringstream record;
	while (getline(input, line))
	{
		PersonInfo info;
		record.clear();
		record.str(line);
		record >> info.name;
		while (record >> word)
		{
			info.phones.push_back(word);
			people.push_back(info);
		}
	}
	for (auto &c : people)
	{
		cout << c.name << endl;
		for (auto & p : c.phones)
		{
			cout << p << " " << endl;
		}
	}
	system("pause");
	return 0;
}

练习8.14:

我们为什么将 entry 和 nums 定义为 const auto& ?

解答:

首先因为他们都是类类型,不是内置类型,所以用引用的方式;其次程序中这两个参数只用于访问对象而不修改对象,所以定义为常量类型。 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值