IO
w代表宽字符,f代表file,s代表string,但指的是内存string对象。
其类型的不同并不会影响使用,通过继承机制,我们可以像如普通操作iostream一样操作fstream和sstream。
IO对象无初始化参数,无法拷贝也无法赋值。
由于在输入或输出时会改变状态,因此返回的是非const引用。
返回的实际是
当一个流发生错误,这个流就不能被继续使用了。
因为它进入了错误状态。
描述IO流对象的状态总共有4个,由四个位表示,分别是
- badbit,表示发生了无法恢复的问题
- failbit,表示发生了可以恢复的问题,当badbit为置位也为置位
- eofbit,表示流到了文件末尾
- goodbit,表示流没有发生错误,当错误位都为复位时为置位
因此,goodbit与failbit是正好相对的。
置位:将该位变为1
复位:将该位变为0
这四种状态被存储在iostate中,可以通过rdstate()来获取当前的iostate。
通过4个分别检测四种状态的情况的函数,即可对应进行检测。
通过clear函数可以将状态复位,并且可以通过参数来指定复位的位置。
setstate正好与clear相反,是根据参数类指定置位的位置。
具体clear与setstate是如何根据传入参数而选择位置的,暂时还没懂。
缓冲
由于设备的写操作可能很费事,因此程序会先将输出内容暂存到缓冲区。之后再将缓冲区的内容一并输出,大大提高性能。
缓冲区刷新就是指将缓冲区内容输出并清空。
缓冲区刷新将在以下几种情况刷新。
- 程序正常结束,在return 0时刷新。当非正常结束时,不会刷新。
- 当缓冲区满的时候。
- 当使用endl,flush和end操纵符时。flush仅会刷新缓冲区,end会额外输出一个空字符,endl额外输出一个换行符。
- 可以通过unitbuf设置流的状态来立即清空缓冲区,在cerr中unitbuf是默认设置的,因此其内容每次都会直接输出。
- 当输出流被关联到其他流时,当被关联流读写时,其本身就会刷新。cin与cerr都关联cout,因此读写cin,cerr会使cout刷新。
通过unitbuf操纵符,表示之后所有的写操作后都flush,并可以通过nounitbuf重置。
通过将读操作关联到写操作,可以保证输出的结果必会在用户的后操作前显示出来。
tie
是istream的一个成员函数,通过点运算符调用。
- 无参数。返回指向当前输入流所关联到的输出流的指针。可能返回空指针。
- 一个指向输出流的指针作为参数。将当前输入流关联到输出流。可以传入空指针来解除关联。
多个输入流可以关联到一个输出流。
但一个输入流不能关联到多个输出流。
虽然一般只会将输入流绑定到输出流上,但是实际上输出流也是有tie这个属性。
文件输入输出
继承所有的iostream特性。
由于fstream是iostream的派生类,而在要求使用基类型对象的地方,可以使用派生类替代。因此可以在要求iostream时用fstream替代。
若是open失败,这流的failbit会被置位。其后续操作也将不能继续。
另外,若是对于一个已经打开文件的流,若是再次调用open,则会是失败,failbit也会被置位。
当离开作用域时,会自动调用close。
模式
- in读模式
- out写模式
- app追加模式,每次写操作定位至文件末尾
- ate打开文件时定位至文件末尾
- trunc截断文件,即删除文件中所有内容
- binary二进制读
trunc只有在out时才能才能使用。
trunc与app相冲突。
默认情况下out就附带了trunc,若要不截断,必须显式声明app或in。
fstream类型会以其默认功能的模式打开。
string流
实际上就是对string的操作。主要用来防止缓冲区溢出错误(?)。