IO类
头文件iostream, 是关联到用户的控制台窗口的。我们常用的cin,cout,cerr,>>运算符,<<运算符,getline()函数等。
除了iostream,还有文件流,和string流
头文件fstream (file stream,文件流):它是对文件的操作
头文件sstram (string stream ,string流):它是对string进行读写等操作。
IO类的条件状态
IO操作可能发生错误,有些可以恢复但是有一些不能恢复,IO类定义的一些函数和标志,可以帮助我们访问和操纵流的条件状态。以上的三个流都有一样的标志,标志如下表。
strm::badbit | 用来指出流已崩溃 |
strm::falibit | 用来指出IO操作失败 |
strm::eofbit | 用来指出流到达了文件结束 |
strm::goodbit | 用来指出流未处于错误状态,此时该位为0 |
对应IO类的标志还有相应的检测函数
s.bad() | 若流 s 的 failbit 被置位,则返回 true,也就是表示该流崩溃了 |
s.fail() | 若流 s 的 failbit 或者 badbit 被置位 ,则返回 true,表示流崩溃或者IO操纵失败 |
s.eof() | 若流 s 的 eofbit 被置位 ,则反回 true,表示文件到达文件结束 |
s.good() | 若流 s 处于有效状态,则返回 true ,也就是说 goodbit 位为0 |
这样我们就可以在进行IO操作的时候,检测其对应位是否正常工作,在文件流操作中常用s.eof()来判断文件是否为空。
既然IO类有上面所述的四个位来判断流是否正常工作,那么就有相应的函数来读取这些位,并且可以进行置位与复位等相关操作。
s.rdstate() | 返回流 s 的当前条件状态,返回类型位 strm::iostate |
s.setstate(flags) | 根据给定的 flags 标志位,将流 s 中对应条件状态位置位。flags的类型为 strm::iostate |
s.clear() | 将流 s 中所有条件状态位复位,将流的状态设置为有效。 |
s.clear(flags) | 根据给定的 flags 标志位,将流 s 中对应条件状态位置位。flags 的类型为 strm::iostate |
写下列代码有助于理解
auto O_State = cin.rdstate(); 记住 cin 的当前状态
cin.clear(); 使 cin 所有状态全部置位,即使 cin 有效
之后就可以使用正常使用 cin
cin.setstate(O_State); 将 cin 置为原来的状态
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
复位 failbit 和 badbit ,保持其他标志位不变
刷新输出缓冲区
在IO输出时,我们写的输出打印文本串,可能被直接打印出来,但也有可能被操作系统保存在缓冲区中,随后再打印。有了缓冲机制,操作系统就可以将程序的多个输出操作组合成单一的系统级写操作。这样可以给操作系统带来很大的性能提升。
缓冲刷新也就是使数据真正写到设备或者文件中。当缓冲区满了的时候需要缓冲刷新才能继续写入缓冲区。
1)当程序结束时,缓冲刷新会被执行。
2)我们常用的endl 结束换行其实就是一种显示的缓冲刷新。相应的还有ends,和flush
cout<<" hi! "<<endl; 输出一个 hi! 和一个换行,然后缓冲刷新。
cout<<" hi! "<<flush; 输出一个 hi!,然后缓冲刷新,不附带任何额外字符;
cout<<" hi! "<<ends; 输出一个 hi! 和一个空字符,然后缓冲刷新。
3)还有就是可以用操纵符unitbuf 用流输出 unitbuf 后每个输出都自动进行一次 flush ,即不带字符缓冲刷新。nounitbuf 操作符就是让其缓冲刷新机制恢复正常使用。
cout<<unitbuf;
任何输出都立即刷新,无缓冲;
cout<<nounitbuf;
回到正常的缓冲刷新机制。