1、面向对象的标准库
(1)面向对象是C++的一大特色,他的标准库自然也不例外,统统都是面向对象设计的。标准库使用了继承(inheritance)来定义一组面向对象(object-oriented)类。IO类型定义在三个独立的头文件中:iostream定义读写控制窗口的类型;fstream定义读写已命名文件的类型;sstream定义读写存储在内存中的string对象的类型。各头文件包含的类型及其含义以及各类型之间的继承关系:头文件iostream :istream 从流中读取,ostream 写的流中,iostream 对流进行读写;其是从istream 和 ostream中派生而来;
头文件fstream:ifstream 从文件中读取,由istream派生而来;ofstream 写到文件中去,由ostream派生而来;fstream 对文件进行读写,其是从iostream中派生而来;
头文件sstream:isstringstream 从string对象中读取,由istream派生而来;osstringstream 写到string对象中去,由ostream派生而来;sstream对string对象进行读写;其是从iostream中派生而来;
下图为iostream 继承层次图
(2)IO对象不可复制或赋值:流对象不能存储在vector等容器中;形参或返回类型也不能为流类型,但可以是流对象的指针或引用,且引用必须为非const:
ofstream &print(ofstream &);//OK
ofstream out2;
while(print(out2));//ok
2、条件状态
通常我们在使用io库的时候会出现各种异常,通过以下函数可以获取条件状态
strm::iostate 机器相关的整型名,由各个 iostream 类定义,用于定义条件状态
strm::badbit strm::iostate 类型的值,用于指出被破坏的流
strm::failbit strm::iostate 类型的值,用于指出失败的 IO 操作
strm::eofbit strm::iostate 类型的值,用于指出流已经到达文件结束符
s.eof() 如果设置了流 s 的 eofbit值,则该函数返回 true
s.fail() 如果设置了流 s 的failbit 值,则该函数返回 true
s.bad() 如果设置了流 s 的 badbit 值,则该函数返回true
s.good() 如果流 s 处于有效状态,则该函数返回 true
s.clear() 将流 s 中的所有状态值都重设为有效状态
s.clear(flag) 将流 s 中的某个指定条件状态设置为有效。flag 的类型是strm::iostate
s.setstate(flag) 给流 s 添加指定条件。flag 的类型是 strm::iostate
s.rdstate() 返回流 s 的当前条件,返回值类型为 strm::iostate
(1)条件状态总结
- 所有流对象都包含一个条件状态成员,该成员是strm::iostate类型的对象,以二进制位的形式使用。可使用clear和setstate来操作和管理条件状态成员,他们常与badbit,eofbit,failbit,goodbit以及位或“|”结合起来使用
- 所有流对象还包括:failbit, eofbit, badbit和goodbit是四个strm::iostate类型的常量值,他们本身分别表示一种条件状态,具体如下表:
常量 | 含义 | fail标志位 | oef标志位 | bad标志位 |
ios::badbit | 输入(输出)流出现致命错误,不可挽回 | 0 | 0 | 1 |
ios::eofbit | 已达到文件结束 | 0 | 1 | 0 |
ios::failbit | 输入(输出)流出现非致命错误,可挽回 | 1 | 0 | 0 |
ios::goodbit | 流状态完全正常 | 0 | 0 | 0 |
- badbit, eofbit, failbit,goodbit构成了四个基本流状态。
- 用bad(), fail(), eof()和good()操作可以检测流状态是否属于,还可以用rdstate()来返回整个条件状态成员。
(2)多种状态的处理
可以通过多次调用setstate或者clear函数实现。或者是使用按位或(OR)操作符在一次调用中“传递两个或更多状态为”的值。
Is.setstate(ifstream::badbit|ifstream::failbit)
或者
Is.badbit|is.failbit
3、输出缓冲区管理
下面几种情况将导致输出缓冲区中的内容被刷新到输出设备或文件:
1) 程序正常结束。作为main返回工作的一部分,将清空所有输出缓冲区;
2) 在一些不确定的时候,缓冲区可能已经满了。在这种情况下,缓冲区将会在写下一个值之前刷新;
3) 用操作符(manipulator)显式地刷新缓冲区,例如 endl,flush等;
4) 在每次输出操作执行后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区;
5) 可将输出流与输入流关联(tie) 起来。在这种情况下,在读输入流时将刷新其关联的输出流缓冲区。
刷新缓冲区的方法:
endl操纵符 输出一个换行符,并刷新缓冲区
ends操纵符 输出一个空字符null,然后刷新缓冲区
flush操纵符 直接刷新缓冲区,不添加任何字符
unitbuf操纵符 它在每次执行完写操作后都刷新缓冲区
将输入和输出关联起来,用tie函数实现:
cin.tie(&cout); // tiecin and cout
ostream* old_tie = cin.tie();
cin.tie(0); // break tie between cin and cout
cin.tie(&err); // a new tie
cin.tie(old_tie); // restablishtie between cin and cout
4、文件的输出和输入
C++ 通过以下几个类支持文件的输入输出:
l ofstream: 写操作(输出)的文件类 (由ostream引申而来)
l ifstream: 读操作(输入)的文件类(由istream引申而来)
l fstream: 可同时读写操作的文件类 (由iostream引申而来)
(1)文件流对象的使用
为了能够读写文件,我们首先要建立一个对象,并且将它们绑定在需要的文件上,例如:
ifstream infile(ifile.c_str()); //ifile is a filename
ofstream outfile (ofile.c_str()); //ofile is a filename
然后,绑定文件要通过一个流对象打开一个文件,我们使用它的成员函数open():
Ifile.open(“in”);
Ofile.open(“out”);
(2)一些注意事项
检查文件打开是否成功。
将文件流与新文件重新绑定:这是当要将流与新文件重新绑定时,需要先关闭现在的文件(close)然后打开新文件。
清除文件流的状态时要使用clear函数。
4、文件的模式
在打开文件使用需要使用open函数如下所示:
void open (constchar * filename, openmode mode);
这里filename 是一个字符串,代表要打开的文件名,mode 是以下标志符的一个组合:
ios::in | 为输入(读)而打开文件 |
ios::out | 为输出(写)而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 所有输出附加在文件末尾 |
ios::trunc | 如果文件已存在则先删除该文件 |
ios::binary | 二进制方式 |
这些标识符可以被组合使用,中间以”或”操作符(|)间隔。例如,如果我们想要以二进制方式打开文件"example.bin" 来写入一些数据,我们可以通过以下方式调用成员函数open()来实现:
ofstream file;
file.open ("example.bin", ios::out | ios::app | ios::binary);
ofstream, ifstream 和 fstream所有这些类的成员函数open 都包含了一个默认打开文件的方式,这三个类的默认方式各不相同:
类 | 参数的默认方式 |
ofstream | ios::out | ios::trunc |
ifstream | ios::in |
fstream | ios::in | ios::out |
只有当函数被调用时没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。
只有当函数被调用时没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。
由于对类ofstream, ifstream 和 fstream 的对象所进行的第一个操作通常都是打开文件,这些类都有一个构造函数可以直接调用open 函数,并拥有同样的参数。这样,我们就可以通过以下方式进行与上面同样的定义对象和打开文件的操作:
ofstream file ("example.bin", ios::out |ios::app | ios::binary);
两种打开文件的方式都是正确的。
你可以通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了:
bool is_open();
它返回一个布尔(bool)值,为真(true)代表文件已经被顺利打开,假( false )则相反。
参考:
http://blog.youkuaiyun.com/jiangxinyu/article/details/7875931;
http://www.cnblogs.com/konyel/articles/1332867.html;