IO 类

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
2
3
4
ofstream out1, out2;
out1 = out2; //错误,不能对IO对象赋值
ofstream print(ofstream); //错误,不能初始化ofstream对象
out2 = print(out1); //错误,不能拷贝流对象

  由于不能拷贝IO对象,因此我们也不能将形参或者返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。
读写一个IO对象会改变其状态,因此传递和返回的引用不能时const的。

条件状态

表2 IO库条件状态

strm::iostate strm是一种IO类型,如表1列出。iostate是一种机器相关类型,提供了表达状态条件的完整功能。
strm::badbit 指出流已经崩溃
strm::failbit 指出一个IO操作失败
strm::eofbit 指出流已经到达文件结束
strm::goodbit 指出流未处于错误状态。此值保证为0
1
2
int ival;
cin >> ival;

如果键入Boo,则会报错,cin进入错误状态,输入一个文件结束符号标识,同样会报错;
由于流可能出现错误状态,因此在使用一个流之前要注意检查流的状态,例如直接使用一个条件:

1
2
while(cin >> word)
//......

检查流的状态
badbit:表示系统级错误,如不可恢复的错误,一旦badbit被置位,流就无法使用;
failbit:当发生可恢复错误时被置位,例如期望读取一个数值却读取到一个字符,这种情况流还可以被修正后继续使用;
当流到达文件结束的位置,eofbit和failbit都被置位。good位为0,表示未发生错误。
管理流对象

1
2
3
4
auto 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
2
cout << unitbuf;    //所有输出操作之后都会立即刷新缓冲区
cout << nounitbufl //回到正常的刷新机制

注意:如果程序崩溃,输出缓冲区不会被刷新,它所输出的内容很可能驻留在缓冲区中等待打印。因此,
在调试程序时,一定需要确定那些你认为已经输出的数据确实已经刷新了。否则,可能花大量的时间去最终程序为什么没有执行,但是实际上已经输出了,只是没有打印出来。
关联输入和输出流
当一个输入流关联到一个输出流的时候,任何试图从输入流读取数据的操作都会刷新关联的输出流。标准库已经将cin和cout关联在一起,

1
cin >> ival;

导致输出流cout被刷新。