C++ Prime 第八章 IO类

2023-03-31~2023-03-31

IO类

  • istream输入流,提供输入操作
  • ostream输出流,提供输出操作 alt

条件状态

  • 一个流一旦发生错误,后续的IO操作都会失败。最简单的方式是将流作为一个条件使用,这样检查流是否正常同时也能进行IO操作
while(cin >> word){};

8.1.2节练习

alt

练习8.1~8.2:

#include<iostream>
using namespace std;

istream& myIstream(istream& is)
{
	string temp;
	while (is >> temp)
	{
		cout << temp << endl;
	}
	is.clear();
	return is;
}

int main()
{
	istream &temp =  myIstream(cin);
	cout << temp.good() << endl;
	system("pause");
	return 0;
}

练习8.3:

输入的数据与i的类型不同或者无法隐式的转换成i的类型的数据时会终止

管理输出缓冲

  • 每个输出流都管理一个缓冲区,用来保存程序读写的数据,缓冲区被刷新相当于程序对于写或者读的操作真正被执行。

刷新输出缓冲区

  • endl:向缓冲区插入一个空字符,然后刷新缓冲区
  • flush:刷新缓冲区
  • unitbuf:后续的每次输出操作都刷新缓冲区
  • nounitbuf:回到正常的缓冲方式
cout << unitbuf;
....... // 每次输出操作都刷新缓冲区
cout << nounitbuf;
......  // 回到正常的缓冲方式

alt

关联输入和输出流

  • 当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。(标准库将cout和cin关联在一起)
string ival;
cin >> ival; // 会导致cout的缓冲区被刷新
  • tie(ostream*)接受一个指向ostream的指针,将自己关联到ostream
ostream *old_tie = cin.tie(nullptr); // 1、将cin不在与其他流关联。2、创建一个ostream类型指针
cin.tie(old_tie); // cin接收一个ostream类型的指针,所以cin与cout重新建立关联

文件输入输出

  • 使用fsteam替代iostream
  • ofstream对象可以实现对文件的写操作
  • ifstream对象可以实现对文件的读操作
  • fstream对象既可以读又能写

8.2.1节练习

alt

练习8.4:

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

void openMyFile()
{

	string fileName = "test.txt";
	ifstream in(fileName);
	vector<string> vec;
	string line;
	while (getline(in, line))
	{
		vec.push_back(line);
	}
	for (auto temp : vec)
	{
		cout << temp << endl;
	}
}

int main()
{
	openMyFile();
	system("pause");
	return 0;
}

练习8.5:

#include<iostream>
#include<vector>
#include<fstream>
using namespace std;
 
void openMyFile()
{
	string fileName = "test.txt";
	ifstream in(fileName);
	vector<string> vec;
	while (in)
	{
		string temp;
		in >> temp;
		vec.push_back(temp);
	}
	for (auto temp : vec)
	{
		cout << temp << endl;
	}
}

int main()
{
	openMyFile();
	system("pause");
	return 0;
}

练习8.6:

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



class Sales_data
{
public:
	friend istream& read(istream&, Sales_data&);
	Sales_data() = default;
	Sales_data(string& bNo) :bookNo(bNo) {};
	Sales_data(istream& is)
	{
		read(is, *this);
	};
	string bookNo;
	unsigned units_sold = 0;
	double revenue = 0;

	string isbn() const
	{
		return this->bookNo;
	}

	Sales_data& combine(Sales_data& temp)
	{
		this->revenue += temp.revenue;
		this->units_sold += temp.units_sold;
		return *this;
	}

	double avg_price() const
	{
		return this->revenue / this->units_sold;
	}
};

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

ostream& print(ostream& os, const Sales_data& s)
{
	os << s.isbn() << " " << s.units_sold << " "
		<< s.revenue << " " << s.avg_price();;
	return os;
}

Sales_data add(Sales_data& s1, Sales_data& s2)
{
	Sales_data sum = s1;
	s1.combine(s2);
	return sum;
}


void openMyFile(string fN)
{
	ifstream in(fN);
	Sales_data total;
	read(in, total);
	Sales_data trans;
	while (read(in, trans))
	{
		if (total.isbn() == trans.isbn())
		{
			total.combine(trans);
		}
		else
		{
			print(cout, total);
			cout << endl;
			total = trans;
		}
	}
	print(cout, total);
}

int main(int argc, char **argv)
{
	//  假设读取的文件结构如下
	//  1211 100 100
	//	1211 100 100
	//	1211 100 100
	//	1201 50 50
	//	1201 50 50
	//	1209 10 10
	//	1210 10 10
	//	1211 10 10
	openMyFile(argv[1]);
	system("pause");
	return 0;
}

文件模式

alt

以out模式打开文件会丢弃已有数据

以下均会丢弃已有数据:

	ofstream out1("fileName");
	ofstream out2("fileName", ofstream::out);
	ofstream out2("fileName", ofstream::out | ofstream::trunc);
  • 如果要保留数据可以使用in方式打开,或者指定app模式
ofstream out;
out.open("fileName", ofstream::app);
out.close();

8.2.2节练习

alt

练习8.7:

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

class Sales_data
{
public:
	friend istream& read(istream&, Sales_data&);
	Sales_data() = default;
	Sales_data(string& bNo) :bookNo(bNo) {};
	Sales_data(istream& is)
	{
		read(is, *this);
	};
	string bookNo;
	unsigned units_sold = 0;
	double revenue = 0;

	string isbn() const
	{
		return this->bookNo;
	}

	Sales_data& combine(Sales_data& temp)
	{
		this->revenue += temp.revenue;
		this->units_sold += temp.units_sold;
		return *this;
	}

	double avg_price() const
	{
		return this->revenue / this->units_sold;
	}
};

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

ostream& print(ostream& os, const Sales_data& s)
{
	os << s.isbn() << " " << s.units_sold << " "
		<< s.revenue << " " << s.avg_price() << endl;
	return os;
}

Sales_data add(Sales_data& s1, Sales_data& s2)
{
	Sales_data sum = s1;
	s1.combine(s2);
	return sum;
}

void openMyFile(string fN, string RN)
{
	ifstream in(fN);
	Sales_data total;
	read(in, total);
	Sales_data trans;

	ofstream out(RN);

	while (read(in, trans))
	{
		if (total.isbn() == trans.isbn())
		{
			total.combine(trans);
		}
		else
		{
			print(cout, total);
			cout << endl;
			print(out, total);
			total = trans;

		}
	}
	print(cout, total);
	print(out, total);
	out.close();
}

int main(int argc, char** argv)
{
	openMyFile(argv[1], argv[2]);
	system("pause");
	return 0;
}

练习8.8:

将ofstream out(RN);修改为ofstream out(RN, ofstream::app);即可

string流

  • istringstream从string读取数据
  • ostringstream向string写入数据
  • sstringstream既写又能读string

8.3.1节练习

alt

练习8.9:

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

istream& myIstream(istream& is)
{
	string temp;
	while (is >> temp)
	{
		cout << temp << endl;
	}
	is.clear();
	return is;
}

int main()
{
	istringstream ss("abcd1234");
	istream& temp = myIstream(ss);
	cout << temp.good() << endl;
	system("pause");
	return 0;
}

练习8.10:

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

void test()
{
	ifstream in("test_word.txt");
	string temp;
	vector<string> vec;
	while (getline(in, temp))
	{
		vec.push_back(temp);
	}
	istringstream ss;
	string word = "";
	for (auto line : vec)
	{
		for (auto str : line)
		{
			if (isspace(str))
			{
				ss.str(word);
				word = "";
			}
			else
			{
				word += str;
			}
		}
	}
	ss.str(word);
	
}

int main()
{
	test();
	system("pause");
	return 0;
}

练习8.11:

#include<iostream>
#include<vector>
#include<fstream>
#include<string>
#include<sstream>
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);
	}
	cout << people.size() << endl;
	for (auto& p : people)
	{
		cout << "name:" << p.name << "phone:";
		for (auto ph : p.phones)
		{
			cout << ph << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

练习8.12:

没有需要初始化的需求,数据需要通过输入源输入,而不是通过初始化获得

8.3.2节练习

alt

练习8.13:

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

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

int main()
{
	string line, word;
	vector<PersonInfo> people;
	ifstream in("test_phone.txt");
	while (getline(in, line))
	{
		cout << line << endl;
		PersonInfo info;
		istringstream record(line);
		record >> info.name;
		while (record >> word)
		{
			info.phones.push_back(word);
		}
		people.push_back(info);
	}
	cout << people.size() << endl;
	for (auto& p : people)
	{
		cout << "name:" << p.name << "phone:";
		for (auto ph : p.phones)
		{
			cout << ph << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

练习8.14:

该程序不涉及到修改源电话号码数据,所以用const修饰

C++Prime学习笔记 文章被收录于专栏

勇敢和愚蠢只有一剑之差

全部评论
楼主你这是分享的一本书里面的?能直接分享下书名不
点赞 回复 分享
发布于 2023-04-01 18:15 陕西
这个平时可以用啥工具练习c++呢
点赞 回复 分享
发布于 2023-04-01 18:48 广东

相关推荐

11-24 11:23
门头沟学院 C++
点赞 评论 收藏
分享
点赞 2 评论
分享
牛客网
牛客企业服务