zoukankan      html  css  js  c++  java
  • C++ Primer 第四版读书笔记(七)之标准IO库

    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::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

    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 一个打开并检查输入文件的程序

    五、字符串流


  • 相关阅读:
    Android studio初次安装启动时弹出unable to access android sdk add-on list提示的解决方法
    SQL Server(MSSQLSERVER) 请求失败或服务未及时响应,有关详细信息,请参见事件日志或其他的适用的错误日志。
    Docker启动时提示Get Permission Denied while trying to connect解决方法
    Docker版本与centos和ubuntu环境下docker安装介绍
    菜鸟宝典之Windows Server 2012 R2上PHP、MySQL环境搭建
    Java入门指南-04 顺序、分支、循环
    Java入门指南-03 操作符与表达式
    Java入门指南-02 变量
    Java入门指南-01 基本概要说明
    JavaWeb零基础入门-02 开发环境安装
  • 原文地址:https://www.cnblogs.com/SunkingYang/p/11049233.html
Copyright © 2011-2022 走看看