C++ Primer 第四版读书笔记(七)之标准IO库

来源:互联网 发布:淘宝客佣金怎么关闭 编辑:程序博客网 时间:2024/04/29 04:28

C++的输入/输出由标准库提供。标准库定义了一组类型,支持对文件和控制窗口等设备的读写(IO)。还定义了其他一些类型,使string对象能够像文件一样操作,从而使我们无需IO就能实现数据与字符之间的转换。一般来说,类的设计者还可以很方便地使用IO标准库设施读写自定义类的对象。类类型通常使用IO标准库为内置类型定义的操作符和规则来进行读写。

一、面向对象的标准库

迄今为止,我们已经使用IO类型和对象读写数据流,它们常用于与用户控制窗口的交互。当然,实际的程序不能仅限于对控制窗口的IO,通常还需要读或写已命名的文件。此外,程序还应该能方便地使用IO操作格式化内存中的数据,从而避免读写磁盘或其他设备的复杂性和运行代价。应用程序还需要支持宽字符语言的读写。

一般而言,通过继承关联起来的类型都共享共同的接口。当一个类继承另一个类时,这两个类通常可以使用相同的操作。更确切地说,如果两种类型存在继承关系,则可以说一个类“继承”了其父类的行为——接口。

IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中string对象。在fstream和sstream里定义的每种类型都是从iostream头文件中定义的相关类型派生而来。

对IO类型使用继承还有另外一个重要的含义:如果函数有基类类型的引用形参时,可以给函数传递其派生类型的对象。这就意味着:对istream&进行操作的函数,也可使用ifstream或者istringstream对象来调用。

1.1 国际字符的支持

每一个IO头文件都定义了char和wchar_t类型的类和标准输入/输出对象。基于流的wchar_t类型的类和对象在iostream中定义,宽字符文件流类型在fstream中定义,而宽字符stringstream则在sstream头文件中定义。

1.2 IO对象不可复制或赋值

一般情况下,如果要传递IO对象以便对它进行读写,可用非const引用的方式传递这个流对象。对IO对象的读写会改变它的状态,因此引用必须是非const的。

二、条件状态

实现IO的继承正式错误发生根源。一些错误是可恢复的;一些错误则是发生在系统底层,位于程序可修正的范围之外。IO标准库管理一些列条件状态成员,用来标记给定的IO对象是否处于可用状态,或者碰到了哪种特定的错误。IO标准库的条件状态函数标记strm::iostate机器相关的整型名,由各个iostream类定义,用于定义条件状态strm::badbitstrm::iostate类型的值,用于指出被破坏的流strm::failbitstrm::iostate类型的值,用于指出失败的IO操作strm::eofbitstrm::iostate类型的值,用于指出流已经达到文件结束符s.eof()如果设置了流s的eofbit值,则该函数返回trues.fail()如果设置了流s的failbit值,则该函数返回trues.bad()如果设置了流s的badbit值,则该函数返回trues.good()如果流s处于有效状态,则该函数返回trues.clear()将流s中的所有状态值都重设为有效状态s.clear(flag)将流s中的某个指定条件状态设置为有效。flag的类型是strm::iostates.setstate(flag)给流s添加指定条件。flag的类型是strm::iostates.rdstate()返回流s的当前条件,返回值类型为strm::iostate

2.1条件状态

所有流对象都包含一个条件状态成员,该成员由setstate和clear操作管理。

2.2 流状态的查询和控制

三、输出缓冲区的管理

3.1 输出缓冲区的刷新

endl:用于输出一个换行符并刷新缓冲区

flush:用于刷新流,但不在输出中调价任何字符

ends:比较少用,在缓冲区中插入空字符null,然后再刷新它

3.2 unitbuf操纵符

如果需要刷新都有输出,最好使用unitbuf操纵符。这个操纵符在每次执行完些操作后都刷新流。

3.3 将输入和输出绑定在一起

交互式系统通常应确保它们的输入和输出流是绑定在一起的。这样做意味着可以保证任何输出,包括给用户的提示,都在试图读之前输出。

四、文件输入和输出

fstream头文件定义了三种支持文件IO的类型:

(1)ifstream,由istream派生而来,提供读文件的功能;

(2)ofstream,由osteam派生而来,提供写文件的功能;

(3)fstream,由iostream派生而来,提供读写同一个文件的功能。

4.1文件流对象的使用

需要读写文件时,则必须定义自己的对象,并将他们绑定在需要的文件上。

在使用fstream对象之前,还必须使这些对象捆绑要读写的文件。

调用open成员函数将已存在的fstream对象与特定文件绑定。为了实现读写,需要将指定的文件打开并定位,open函数完成系统指定的所有需要的操作。

4.1.1 检查文件打开是否成功

打开文件后,通常要检验打开是否成功,这是一个好习惯。

ifstream infile;

infile.open("in");

if(!infile)

{

...........................

return -1;

}

4.1.2 将文件流与新文件重新捆绑

fstream对象一旦打开,就保持与指定的文件相关联。如果要把fstream对象与另一个不同的文件关联,则必须先关闭(close)现有的文件,然后打开(open)另一个文件。

4.1.3 清除文件流的状态

如果程序员需要用文件流读写多个文件,必须在读另一个文件之前调用clear清除该流的状态。

4.2 文件模式

在打开文件时,无论是调用open还是以文件名作为流初始化的一部分,都需要指定文件模式。每个fstream类都定义了一组表示不同模式的值,用于指定流打开的不同模式。与条件状态标识一样,文件模式也是整型常量。文件流构造函数和open函数都提供了默认实参设置文件模式。

文件模式in打开文件做读操作out打开文件做写操作app在每次写之前找到文件尾ate打开文件后立即将文件定位在文件尾trunc打开文件时清空已存在的文件流binary以二进制模式进行IO操作
out、trunc和app模式只能用于指定与ofstream或fstream对象关联的文件;in模式只能用于指定与ifstream或fstream对象所关联的文件。所有的文件都可以使用ate或binary模式打开。ate模式只在打开时有效:文件打开后将定位到文件尾。以binary模式打开的流则将文件以字节序列的形式处理,而不解释流中的字符。

默认时,与ifstream流对象关联的文件以in模式打开,该模式允许文件做读的操作;与iostream关联的文件则以out模式打开,是文件可写。以out模式打开的文件会被清空:丢弃该文件存储的所有数据。

注:从效果来看,为ofstream对象执行out模式等效于同时指定了out和trunc模式。

4.2.1 对同一个文件作输出和输入运算

默认情况下,fstream对象以in和out模式同时打开。当文件同时以in和out打开时不清空。如果打开fstream所关联的文件时,只使用out模式,而不指定in模式,则文件会清空已存在的数据。如果打开文件时指定了trunc模式,则无论是否同时指定了in模式,文件同样会被清空。

4.2.2 模式是文件的属性而不是流的属性

注:只要调用open函数,就要设置文件模式,其模式的设置可以是显式的也可以是隐式地。如果没有指定文件模式,将使用默认值。

4.2.3 打开模式的有效组合

并不是所有的打开模式都是可以同时指定。有些模式组合式没有意义的:

文件模式的组合out打开文件做写操作,删除文件中已有的数据out | app打开文件做写操作,在文件尾写入out | trunc与out模式相同in打开文件做读操作in | out打开文件做读、写操作,并定位于文件开头处in | out | trunc打开文件做读、写操作,删除文件中已有的数据
4.3 一个打开并检查输入文件的程序

五、字符串流


0 0
原创粉丝点击