C++包括两类IO库,一种是基于流形式的IO库,另一种是C风格的IO函数库,下面我会分别来阐述,重点还是放在C++的流形式IO上。
IO类
IO类继承关系
基于流的输入和输出围绕抽象的输入输出设备组织而成,这些抽象输入输出设备包括控制台窗口,文件和内存中的string对象,并且这些类都是模板化的,类的继承形式如下:
C++的IO类继承架构图
在上面的继承关系图中,
ios_base是接口类,主要管理格式符号和输入输出异常,通常我们不对其进行直接操作,我们需要使用基类时也是使用
basic_ios,用其来管理任意的流操作。不过我们在日常使用中,不会直接使用上图中的类名,而是通过了别名来进行调用,别名的用法如下代码所示,其中以w开头的都是宽字符类型使用的。在IO流的使用中,
一定要注意的是不能够使用拷贝构造和赋值语句,因为在基类中这些函数就已经被私有化了。还有两个库iomanip和stdiostream需要关注,前者声明了格式化IO的一些操作,后者用于混合使用C和C++的IO机制。
/* Defined in header
*/
typedef basic_ios
ios; typedef basic_ios
wios; /* Defined in header
*/ typedef basic_streambuf
streambuf; typedef basic_streambuf
wstreambuf; /* Defined in header
*/ typedef basic_filebuf
filebuf; typedef basic_filebuf
wfilebuf; /* Defined in header
*/ typedef basic_stringbuf
stringbuf; typedef basic_stringbuf
wstringbuf; /* Defined in header
*/ typedef basic_istream
istream; typedef basic_istream
wistream; /* Defined in header
*/ typedef basic_ostream
ostream; typedef basic_ostream
wostream; /* Defined in header
*/ typedef basic_iostream
iostream; typedef basic_iostream
wiostream; /* Defined in header
*/ typedef basic_ifstream
ifstream; typedef basic_ifstream
wifstream; typedef basic_ofstream
ofstream; typedef basic_ofstream
wofstream; typedef basic_fstream
fstream; typedef basic_fstream
wfstream; /* Defined in header
*/ typedef basic_istringstream
istringstream; typedef basic_istringstream
wistringstream; typedef basic_ostringstream
ostringstream; typedef basic_ostringstream
wostringstream; typedef basic_stringstream
stringstream; typedef basic_stringstream
wstringstream;
我们平时接触最多的还是标准库中已经被预定义的cin(wcin),cout(wcout),cerr(wcerr),clog(clog),他们分别对应着标准输入流,标准输出流,标准错误输出流和标准日志输出流,不过可以通过rdbuf()方法来改变这些流对象的缓冲区,也就改变了这些流对象的标准功能,注意cerr流无缓冲区。
条件状态
在流对象中有一个非常重要的特性是条件状态,通过该特性我们可以了解一个流对象的当前状态以及是否能正常工作,因为当一个错误发生时,该流对象随后的操作就必然会失败。所有的流对象都有如下四种条件状态:goodbit,badbit,eofbit,failbit。goodbit代表流对象正常,badbit代表该流对象崩溃了,不可恢复,eofbit表示该流对象已经处于流的结束位置,failbit表示某次IO操作失败,但该错误可恢复。同时还提供了一些方法如eof(),fail(),bad(),good(),clear(),setstate(),rdstate()等来对条件状态进行判断和操作。我们以一段代码来说明如何使用这些方法:
#include
#include
#include
using namespace std; int main(int argc, char* argv[]) { string obj{"just a test!"}; stringstream ss(obj); stringstream::iostate state = ss.rdstate(); /* 读取该流对象中的条件状态 */ ss.setstate(state | stringstream::failbit); /* 将该流对象的failbit置位 */ string tmp; while(ss>>tmp) /* 因为错误存在,该流对象不会输入 */ { cout<
>tmp) { cout<
结果: true another test! true
接下来我用一个表格来说明条件状态位与条件判断方法的关系: