C++ Primer 第八章 8.3 练习和总结

8.3 string的输入和输出

8.3.1 使用istringstream

和之前的文件的输入和输出一样
string的io类型也有三个类别,分别是

istringstream
ostrngstream
stringstream

同样这三个类都是iostream的子类。
他们有自己的操作。

在这里插入图片描述

和文件的输入和输出的操作不一样的是,这里传入的s不是关联字符串,而是保存s的拷贝

istringstream

如果我想处理处理字符串中的单个单词,我们可以使用istringstream。

所谓的单个单词,就是使用空格作为间隔的一串字符

"123 321 321"

可以看作三个单词。

ostringstream

如果我们想向string中添加内容时,我们可以使用ostringstream,这样做有时比字符串拼接更方便。

因为字符串拼接会一直创建对象,+一次,创建一个,而ostringstream则是输入到字符串的流中,再统一操作,这样提高了性能。

另一方面,数值类型是无法直接用"+"拼接为字符串的,但是我们使用ostringstream对象来完成。

示例如下:

ostringstream scout;
	int a = 1;
	double b = 3.123;
	char c = 'd';
	scout << a << " " << b << " " << c;
	cout << scout.str();

	string str = "";
	str + 1;//error 错误,string标准库没有重载此操作符

练习

8.9

istream& get_istream(istream& temp_cin) {
	string  content = "";
	auto old_state = temp_cin.rdstate();
	while (true) {
		temp_cin >> content;
		cout << content << endl;
		if (temp_cin.eof()) {
			temp_cin.setstate(old_state);
			break;
		}
	}
	return  temp_cin;
}

string str = "人们需要希望 英雄永垂不朽";
	//关联一个字符串对象
	istringstream sin(str);
	get_istream(sin);

8.10

string temp_str;
	std::vector<string> vec = {"今天是2020/2/7 距离开学还有xx天","天气太冷了 圣三一就要追来了","劳拉"};
	for (const auto & str :vec) {
		istringstream sin(str);
		while (sin >> temp_str) {
			cout << temp_str << endl;
		}
	}

8.11

string line, word;
	std::vector<PersonInfo> people;
	istringstream record;
	//istringstream record(line);//错误,因为保存的是line的拷贝
	while (std::getline(cin,line)) {
		PersonInfo info;
		record.str(line);
		record >> info.name;
		//cout << info.name << endl;
		while (record>>word)
		{
			info.phones.push_back(word);
		}
		people.push_back(info);
		record.clear();
	}

	for (const auto &item:people) {
		cout << item.name<<std::ends;
		for (const auto& temp_phone:item.phones) {
			cout << temp_phone << std::ends;
		}
		cout << endl;
	}

8.12

string对象的默认初始化为空字符,并不会产生未定义的行为,所以可以不使用类内初始化。‘

8.3.2使用ostringstream

练习

8.13

string line, word;
	std::vector<PersonInfo> people;
	istringstream record;
	ifstream fin("phone.txt");
	//istringstream record(line);//错误,因为保存的是line的拷贝
	while (std::getline(fin,line)) {
		PersonInfo info;
		record.str(line);
		record >> info.name;
		//cout << info.name << endl;
		while (record>>word)
		{
			info.phones.push_back(word);
		}
		people.push_back(info);
		//状态复位,设置流的状态为有效
		record.clear();
	}

	for (const auto &item:people) {
		cout << item.name<<std::ends;
		for (const auto& temp_phone:item.phones) {
			cout << temp_phone << std::ends;
		}
		cout << endl;
	}

	for (const auto& entry:people) {
		//因为是输出流,我们不需要使用传递一个值进去,其实输入流也是,但是读取一个空的string对象没有任何意义
		ostringstream formatted, badNum;
		//为什么需要向formatted和badnum中都写入内容
		//因为我们无法确定,在phones中,哪一个元素不是数字
		//所以两个都要记
		for (const auto & nums:entry.phones) {
			//直接判断是不是纯数字
			if (!valid(nums)) {
				//很有意思,向string对象中写入内容
				badNum << " " << nums;
				//
				break;
			}
			else {
				//因为不知道这里的格式化指的是什么意思,所以就直接写入了
				formatted << " " << nums;
			}
		}
		if (badNum.str().empty()) {
			std::cout << entry.name << " " << formatted.str() << endl;
		}
		else {
			std::cerr << "input errror:" << entry.name << "invalid numbers(s)" << badNum.str() << endl;
		}

8.3.2

为什么是引用,因为引用可以避免拷贝操作,提高效率。
为什么是const引用,因为在代码业务上,entry和nums都不会被改动,因为防止误操作,所以声明为const引用。

发布了54 篇原创文章 · 获赞 6 · 访问量 3334

猜你喜欢

转载自blog.csdn.net/zengqi12138/article/details/104210727