C++Primer:第8章 IO库
第8章:IO库
8.1 IO类
1. IO库类型和头文件
头文件 | 类型 |
---|---|
iostream | istream,wistream从流读取数据 ostream,wostream向流写入数据 iostream,wiostream读写流 |
fstream | ifstream,wifstream从文件读取数据 ofstream,wofstream向文件写入数据 fstream,wfstream读写文件 |
sstream | istringstream,wistringstream从string读取数据 ostringstream,wostringstream向string写入数据 stringstream,wstringstream读写string |
- iostream定义了用于读写流的基本类型;fstream定义了读写命名文件的类型;sstream定义了读写内存string对象的类型。
- ifstream和istringstream继承自istream,ofstream和ostringstream继承自ostream。
2. IO对象无法拷贝赋值
- 由于IO对象不能拷贝和赋值,故形参或返回类型不能是流类型。进行IO操作的函数通常以引用方式传递和返回流。
- 读写一个IO对象会改变其状态,故传递和返回的引用不能是const。
3. 条件状态
条件状态 | 描述 |
---|---|
strm::iostate | strm是IO类型 iostate是一种机器相关的类型,提供表达条件状态的完整功能 |
strm::badbit | 用于指出流已崩溃 |
strm::failbit | 用于指出一个IO操作失败了 |
strm::eofbit | 用于指出流到达了文件结束 |
strm::goodbit | 用于指出流未处于错误状态。此值保证为零 |
s.eof() | 若流s的eofbit置位,则返回true |
s.fail() | 若流s的badbit或failbit置位,则返回true |
s.bad() | 若流s的badbit置位,则返回true |
s.good() | 若流s处于有效状态,则返回true |
s.clear() | 将流s中所有条件状态位复位,将流的状态设置为有效。返回void |
s.clear(flags) | flags的类型是strm::iostate 根据给定的flags标志位,将流s中对应条件状态位复位。返回void |
s.setstate(flags) | flags的类型是strm::iostate 根据给定的flags标志位,将流s中对应条件状态位置位。返回void |
s.rdsate() | 返回流s的当前条件状态,返回类型是strm::iostate |
- 使用一个流前,需先检查流是否处于良好状态。
while(cin>>word)
// ok:读操作成功....
- badbit表示系统级错误,如不可恢复的读写错误,一旦发生流不可再用;failbit表示可恢复错误,如期望读取数据与实际读到数据类型不一致,发生后可修正流仍可使用; 若到达文件结束位置,failbit和eofbit都会被置位; goodbit的值为0,表示流未发生错误。
- good()在所有错误位均未置位的情况下返回true;bad()、fail()、eof()在对应错误位置被置位时返回true;当badbit被置位时,fail()返回ture。故使用good()或fail()确定流的总体状态。
4. 管理输出缓冲
- 输出流的数据可能被立即输出,也可能先暂存在缓冲区再输出。
- 刷新缓冲的原因:程序正常结束,作为main函数的return操作的一部分,刷新缓冲;缓冲区已满,后续数据需先刷新缓冲才能写入缓冲区;使用操纵符如endl显式刷新缓冲区;使用unitbuf设置流的内部状态来清空缓冲区,unitbuf是为cerr设置的,cerr可实现立即刷新;输出流cin、cerr被关联到另一个流cout,读写cin或写cerr会导致cout刷新缓冲区。
- endl换行并刷新缓冲区;flush只刷新缓冲区;ends先插入一个空字符再刷新缓冲区。
- unitbuf通过flush实现每次输出操作后都刷新缓冲区;nounitbuf重置流,使其或非正常缓冲方式。
- 若程序崩溃,输出缓冲区不会被刷新,其输出的数据可能停留在缓冲区中等待打印。
- 不带参数的tie返回指向输出流的指针;接受一个ostream指针的tie将自己关联到此ostream。
8.2 文件输入输出
1. fstream特有的操作
操作 | 描述 |
---|---|
fstream fstrm; | fstream是头文件fstream中定义的一个类型 创建一个未绑定的文件流 |
fstream fstrm(s); | s是string类型或一个指向C风格字符串的指针 创建一个fstream,并打开名为s的文件 此构造函数是explicit |
fstream fstrm(s, mode); | mode包括in、out、app、ate、trunc、binary 创建一个fstream,按指定mode打开名为s的文件 此构造函数是explicit |
fstrm.open(s); | 打开名为s的文件,并将文件与fstrm绑定,返回void |
fstrm.close(); | 关闭与fstrm绑定的文件,返回void |
fstrm.is_open(); | 判断与fstrm绑定的文件是否成功打开,且尚未关闭,返回bool |
- 头文件fstream定义3个类型来支持文件IO:ifstream从一个给定文件读取数据;ofstream向一个给定文件写入数据;fstream可以读写给定文件。
2. 使用文件流对象
- C++11标准中,文件名可以是库类型string对象,也可以是C风格字符数组。旧版本只允许C风格字符数组。
- 调用open()失败时,failbit被置位。故最好检测open()是否打开成功。
if(out)
//检测成功后,再使用out
- 若文件流已打开过文件,它调用open()会失败,并使failbit被置位。若文件流想打开其它文件,必须先关闭再打开。
- 当一个fstream对象离开其作用域时,与之关联的文件会自动关闭。
3. 文件模式
文件模式 | 描述 | 前置要求 | 适合对象 |
---|---|---|---|
in | 以读方式打开 | 无 | ifstream、fstream |
out | 以写方式打开 | 默认trunc | ofstream、fstream |
app | 文件末尾进行写操作 | 默认out,无trunc | ofstream、fstream |
trunc | 截断文件,清空文件后再进行写操作 | 有out | ofstream、fstream |
ate | 打开文件后立即定位到文件末尾 | 无 | 任何对象 |
binary | 以二进制方式进行IO | 无 | 任何对象 |
- 单独以out模式打开文件,会默认使用trunc模式,删除旧内容。
- 以out+app模式或者out+in模式打开文件,可保留文件旧内容。
- ifstream默认以in模式打开;ofstream默认以out模式打开; fstream默认以in+out模式打开。
8.3 string流
1. stringstream特有操作
操作 | 描述 |
---|---|
sstream strm; | sstream是头文件sstream中定义的一个类型 strm是一个未绑定的stringstream对象 |
sstream strm(s); | strm是一个sstream对象,保存string s的一个拷贝。 此构造函数是explicit。 |
strm.str(); | 返回strm所保存的string的拷贝 |
strm.str(s); | 将string s拷贝到strm中,返回void |
- sstream头文件定义3个类型来支持IO:istringtream从string读取数据;ostringtream向string写入数据;stringstream对string读写数据。
- 整行文本处理时,可用istringtream处理行内单词;逐步构造,同一打印输出时使用ostringtream。