学习目标:
IO库
1)IO类 2)文件输入输出 3)string流
学习内容:
一、IO类
1)IO库类型和头文件(p278)
iostream 定义了用于读写流的基本类型
fstream 定义了读写命名文件的类型
sstream 定义了读写内存string对象的类型
值得注意书本中提供表格中w开头的类型和函数名字是针对w_char宽字符使用的。(见p278最下面)
2)IO对象无拷贝或赋值(p279)
不能将形参或返回类型设置为流类型,一般以引用方式传递和返回流。
读写一个IO对象会改变其状态,因此传递和返回的引用不能是const。
注意:8.1.1例子里
ofstream print(ofstream);
这是一个声明,错误地把ofstream作为形成和返回类型,隐形地进行了拷贝操作。(应该用引用类型)
3)条件状态(p279~281)
1.条件状态用于处理IO操作的问题,发现系统地其他错误。
2. IO库定义了4个iostate类型的constexpr值(常量表达式p58),表示特定的位模式。这些值用于表示特定类型的IO条件,可以与位运算符(p137)一起使用来一次性检测或设置多个标志位。
3.badbit表示系统级错误,如不可恢复的读写错误。一旦badbit被置位,流就无法在使用了。
failbit表示发生可恢复错误,如期望读取数值却读取了一个字符。
eofbit和failbit同时置位,则表示到达文件结束位置。
goodbit值为0,表示流未发生错误,而badbit、failbit和eofbit任一个被置位,流检测的条件就是 false。
4.使用位运算进行输入流状态的个别复位(复位failbit和badbit,保持其他其他位置不变)
cin.clear(cin.rdstatebit()&~cin.failbit&~cin.badbit);
//可见failbit和badbit的存储类似00010和00100,它们二进制的位是错开的,通过置位来表示错误。
4)管理输出缓冲(p281~283)
1.缓冲刷新
- 程序正常结束,main执行return操作。
- 缓冲区满,需要刷新缓冲才能读入数据。
- 接收到endl操作符。
- 使用了unitbbuf设置流的内部状态,默认情况下cerr是设置unitbuf的。
- 一个输出流可能被关联到另一个流,如cout关联到cin和cerr,当cin或cerr时就会刷新。
2.unitbuf操作符
如果想每次输出操作后都刷新缓冲区,可以使用unitbuf操作符。
cout<<unitbuf; //所有输出操作后都会立即刷新缓冲区
//任何输出都立即刷新,无缓冲
cout<<nounitbuf //恢复到正常的缓冲方式
注:(见p282)程序崩溃,输出缓冲区不会被刷新。
3.关联输入流和输出流
略。我们可以自定义关联关系,可以取消cin关联cout。(见p283)
二、文件输入输出
1)使用文件流对象
定义文件流对象,将对象与文件关联起来,实现读写操作。
使用open和close成员函数,值得注意如果提供了一个文件名,那么在构造时就会自动调用open。
ifstream in(ifile);//构造一个ifstream并打开给定文件
ofstream out; //输出文件流未关联任何文件
out.open(ifile+".copy");//打开指定文件
if(out)//检查open是否成功
{
//使用文件
}
in.close();//关闭文件
in.open(ifile+"2");//打开另外一个文件
2)文件模式
每个流都有一个关联的文件模式,用来指出如何使用文件。
- in 以读方式打开
- out 以写方式打开
- app 每次写操作前均定位到文件末尾
- ate 打开文件后立即定位到文件末尾
- trunc 截断文件
- binary 以二进制方式打开IO
注:每次打开文件时,都要设置文件模式。(p287)
三、string流(关于string流 用于读取处理整行的string)
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
struct PersonInfo {
string name;
vector<string> phones;
};
//聚合类(p266)
int main()
{
string line, word;
vector<PersonInfo> people;
while (getline(cin, line))
{
PersonInfo info;
istringstream record(line);
record >> info.name;
while (record>>word)
{
info.phones.push_back(word);
}
people.push_back(info);
}
for (const auto &nums : people)
{
cout << "姓名"<<nums.name << endl;
int count = 0;
for (const auto &p : nums.phones)
{
cout << "电话" << ++count << ":" << p << endl;
}
cout<<"----------------------"<<endl;
}
system("pause");
return 0;
}
时间:7.13