C++ Prime 第八章 IO类
2023-03-31~2023-03-31
IO类
- istream输入流,提供输入操作
- ostream输出流,提供输出操作
条件状态
- 一个流一旦发生错误,后续的IO操作都会失败。最简单的方式是将流作为一个条件使用,这样检查流是否正常同时也能进行IO操作
while(cin >> word){};
8.1.2节练习
练习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;
...... // 回到正常的缓冲方式
关联输入和输出流
- 当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。(标准库将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节练习
练习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;
}
文件模式
以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节练习
练习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节练习
练习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节练习
练习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学习笔记 文章被收录于专栏
勇敢和愚蠢只有一剑之差