C++ IO类
表1
头文件 | 类型 |
---|---|
iostream | istream, wistream 从流中读取数据 |
ostream, wostream 向流中写入数据 | |
iostream, wiostream 读写流 | |
fstream | ifstream, wifstream 从文件读取数据 |
ofstream, wofstrkeam 向文件写数据 | |
fstream, wfstream 读写文件 | |
sstream | istringstream, wistringstream 从string中读取数据 |
ostringstream, wostringstream 向string中写入数据 | |
tringstream, wstringstream 读写string |
iostream定义了用于读写流的基本类型,fstream定义了读写命名文件的类型, sstream定义了读写内存的类型
宽字符版本的类型和函数都以一个w开始。宽字符版本的类型和对象与其对应的普通char版本的类型定义在同一个头文件中。
IO类型间的关系
类型ifstream和istringstream都继承自istream。因此,可以像使用istream一样使用ifstream和istringstream。
同样,类型ofstream和ostringstream都继承自istream。
IO对象无拷贝或者赋值
1 | ofstream out1, out2; |
由于不能拷贝IO对象,因此我们也不能将形参或者返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。
读写一个IO对象会改变其状态,因此传递和返回的引用不能时const的。
条件状态
表2 IO库条件状态
strm::iostate | strm是一种IO类型,如表1列出。iostate是一种机器相关类型,提供了表达状态条件的完整功能。 |
---|---|
strm::badbit | 指出流已经崩溃 |
strm::failbit | 指出一个IO操作失败 |
strm::eofbit | 指出流已经到达文件结束 |
strm::goodbit | 指出流未处于错误状态。此值保证为0 |
1 | int ival; |
如果键入Boo,则会报错,cin进入错误状态,输入一个文件结束符号标识,同样会报错;
由于流可能出现错误状态,因此在使用一个流之前要注意检查流的状态,例如直接使用一个条件:1
2while(cin >> word)
//......
检查流的状态
badbit:表示系统级错误,如不可恢复的错误,一旦badbit被置位,流就无法使用;
failbit:当发生可恢复错误时被置位,例如期望读取一个数值却读取到一个字符,这种情况流还可以被修正后继续使用;
当流到达文件结束的位置,eofbit和failbit都被置位。good位为0,表示未发生错误。
管理流对象1
2
3
4auto old_state = cin.rdstate(); //记住cin的状态
cin.clear(); //clear不接收任何参数时,清楚所有错误标志位,使cin有效
process_input(cin); //使用cin
cin.setstate(old_state); //将cin设置为原有状态
带参数的clear()可以接受一个iostate值,表示流的新状态
管理输出缓冲
每个输出流都管理一个缓冲区,用来保存程序读写的数据。例如:1
os << "hello world";
文本串可能被立即打印出来,也可能被操作系统保存在缓冲区,稍后打印。
刷新输出缓冲区
IO库中刷新缓冲区的操作主要有三个:
endl:完成换行并刷新缓冲区;
flush:刷新缓冲区,但是不输出任何额外的字符;
ends:向缓冲区插入一个额外的空字符,然后刷新缓冲区。
unitbuf
unitbuf使流在接下来每一次写操作之后都进行一次flush操作;而nounitbuf使流恢复到正常的系统管理的缓冲区刷新机制。1
2cout << unitbuf; //所有输出操作之后都会立即刷新缓冲区
cout << nounitbufl //回到正常的刷新机制
注意:如果程序崩溃,输出缓冲区不会被刷新,它所输出的内容很可能驻留在缓冲区中等待打印。因此,
在调试程序时,一定需要确定那些你认为已经输出的数据确实已经刷新了。否则,可能花大量的时间去最终程序为什么没有执行,但是实际上已经输出了,只是没有打印出来。
关联输入和输出流
当一个输入流关联到一个输出流的时候,任何试图从输入流读取数据的操作都会先刷新关联的输出流。标准库已经将cin和cout关联在一起,1
cin >> ival;
导致输出流cout被刷新。