c++primer 第8章 IO库

本文详细介绍了C++标准库中的IO库,包括读写控制台和文件的流操作,以及不同类型的流如iostream、fstream和sstream的使用。同时,文章还涵盖了顺序容器如vector和string,泛型算法如排序和搜索,以及关联容器的特性。此外,讨论了动态内存管理和智能指针在提高代码健壮性方面的作用。
摘要由CSDN通过智能技术生成

第Ⅱ部分 C++标准库

  • 第8章 IO库
    • 使用标准库读写与控制台窗口相关联的流
    • 读写命名文件 完成到string对象的内存操作
  • 第9章 顺序容器
    • vector string…
  • 第10章 泛型算法
    • 排序 搜索算法 常用操作
    • 可应用于不同类型的序列 对序列元素的类型限制小
  • 第11章 关联容器
    • 关联容器中的元素通过关键字访问
    • 支持很多顺序容器的操作 也定义了一些特有操作
  • 第12章 动态内存
    • 动态内存管理相关的一些语言特性和库设施
    • 智能指针的一个标准版本
      • 大幅度提高使用动态内存的代码鲁棒性

第8章 IO库

  • IO操作:从设备(文件/控制台窗口)读取数据、向设备写入数据
  • istresm/ostream/cin/cout/cerr/>>/<</getline

8.1 IO类

  • IO头文件(其中w开头的类型/对象用来操纵wchar_t类型数据)
  • iostream 定义用于读写流的基本类型
    • istream,wistream 从流读
    • ostream,wostream 向流写
    • iostream,wiostream 读写
  • fstream 定义读写命名文件的类型
    • ifstream,wifstream 从文件读
    • ofstream,wofatream 向文件写
    • fstream,wfstream 读写文件
  • sstream 定义读写内存string对象
    • istringstream,wistringstream 从string读
    • ostringstream,wostringstream 向string写
    • stringstream,wstringstream 读写string
  • IO类型间的关系
    • 设备类型/字符大小都不会影响IO操作
    • 继承机制
      • 标准库使我们能忽略不同类型的流之间的差异
      • 继承机制能声明一个特定的类继承自另一个类
      • 可以将派生类(继承类/子类)对象当作基类(被继承类/父类)的对象来使用
      • 本节剩余标准库流都可以无差别地应用于普通流/文件流/string流/char或宽字符版本

8.1.1 IO对象无拷贝或赋值

  • 不能拷贝或对IO对象赋值,因此不能将形参或返回类型设置为流对象
  • 通常以引用方式传递和返回流,读写io对象均会改变其状态,所以引用不能是const的

8.1.2 条件状态

  • io操作易发生错误,错误可分为 可恢复错误/超出可修正范围错误
  • 一些函数及标志可帮助访问和操纵流的条件状态
    • 流一旦发生错误,其上后续io操作都会失败,无错时才可读写数据
    • 使用流前应检查是否处于良好状态,确定状态的方法是将其当作条件使用
IO库条件状态
strm:iostateiostate是一种机器无关的类型,提供了表达条件状态的完整功能
strm:badbitstrm:badbit用来指出流已经崩溃
strm:failbitstrm:failbit用来指出一个IO操作失败了
strm:eofbitstrm:eofbit用来指出流到达了文件结束
strm:goodbitstrm:goodbit用来指出流未处于错误状态 此值保证为零
s.eof()若流seofbit置位,则返回true
s.fail()若流sfailbit/badbit置位,则返回true
s.bad()若流sbadbit置位,则返回true
s.good()若流s处于有效状态,则返回true
s.clear()将流s中所有条件状态位复位,将流的状态设置成有效,返回void
s.clear(flags)根据给定的flags标志位,将流s中指定的条件状态位复位。flags类型为strm::iostate,返回void
s.setstate(flags)根据给定的flags标志位,将流s中对应的条件状态位置位。flags类型为strm::iostate,返回void
s.rdstate()返回流s的当前条件状态,返回值类型为strm::iostate
  • 查询流的状态
    • 流做条件使用只知流是否有效,无法告知具体失败原因
    • iostate类型(机器无关) 提供表达流状态的完整功能
      • 定义了4个iostate类型的constexpr值表示特定位模式
      • 应作为位集合使用,一起使用来一次性检测或设置多个标志位
    • badbit 系统级错误(不可恢复读写错误 置位后无法使用)
    • failbit 可被修正错误(流还可以继续使用)
      • 到达文件结束位置 eofbit failbit都会被置位
    • goodbit==0 流未发生错误
    • badbit failbit eofbit 任一置位检测流状态的条件都会失败
    • 定义了一组函数来查询标志位的状态
      • good 所有错误位均未置位情况下返回true
      • bad fail eof 对应错误位被置位时返回true
      • badbit被置位时 fail也会显示true
        • 因此使用good/fail是确定流的总体状态的正确方法 (!fail)
  • 管理条件状态
    • 流对象 rdstate成员返回一个iostate值,对应流的当前状态
    • setstate操作将给定条件位置位,表示发生错误
    • clear 清除(复位)错误标志位
      • 不接受参数版本 复位所有错误
      • 接受一个iostate类型参数版本 复位单一条件状态位

8.1.3 管理输出缓冲

  • 每个输出流管理一个缓冲区,保存程序读写的数据
  • 缓冲机制,可将程序多个输出操作简单组合成单一的系统/设备级写操作(性能提升)
  • 缓冲刷新(数据真正写到输出设备或文件)
    • 程序正常结束
    • 缓冲区满
    • 操纵符endl显式刷新缓冲区
    • unitbuf设置流内部状态清空缓冲区
      • 默认情况下 cerr设置unitbuf 因此写到cerr的内容都是立即刷新的
    • 输出流被关联到另一个流,当读写被关联流时,关联到的流的缓冲区会被刷新
      • cin/cerr都关联到cout 读cin/写cout都会导致cout缓冲区刷新
  • 刷新输出缓冲区
    • endl 换行并刷新缓冲区
    • flush 刷新缓冲区不输出任何额外字符
    • ends 向缓冲区插入一个空字符 刷新缓冲区
  • unitbuf操纵符
    • 使用unitbuf后,每次输出操作后都刷新缓冲区
    • nounitbuf重置流,使其恢复使用正常的系统管理缓冲区刷新机制
std::cout<<unitbuff//后续所有cout输出都会立即刷新缓冲区
std::cout<<nounitbuff//回到正常缓冲方式
  • 如果程序崩溃,输出缓冲区不会被刷新

  • 关联输入和输出流

    • 当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流
    • 交互式系统通常应该关联输入流和输出流,所有输出包括用户提示信息都会在读取操作之前被打印出来
    • tie
      • 不带参数版本 返回指向输出流的指针(关联输出流返回指向该流的指针 未关联到流返回空指针)
      • 接受一个指向ostream的指针 将自己关联到此ostream
    • 可将istream关联到ostream 也可将ostream关联到另一个ostream
    • 每个流同时最多关联到一个流 但多个流可同时关联到同一个ostream

8.2 文件输入输出

  • ifstream 从一个给定文件读取数据
  • ofstream 向一个给定文件写入数据
  • fstream 读写文件
  • 可以用io运算符<</>>来读写文件
  • 用getline从ifstream读取文件
fstream特有的操作
fstream fstrm;创建一个未绑定的文件流
fstream fstrm(s);创建一个fstream,并打开名为s的文件,s可以是string也可以是一个指向C风格字符串的指针
fstream fstrm(s, mode);与前一个构造函数类似,但按指定mode打开文件
fstrm.open(s)打开名为s的文件,并和fstrm绑定
fstrm.close()关闭和fstrm绑定的文件 返回void
fstrm.is_open()返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭

8.2.1 使用文件流对象

  • 可以定义一个文件流对象读写文件 将对象与文件关联起来

  • 创建文件流对象时若提供了文件名,则open会自动被调用

  • 用fstream代替iostream&

    • 在要求使用基类对象的地方,可以用继承类型的对象替代
    • 接受一个iostream类型引用/指针参数的函数,可以用一个对应的fstream类型来调用
  • 成员函数open和close

    • 定义了一个空文件流,可以调用open将其与文件关联起来
      • 若调用open失败,failbit会被置位,检测open是否成功(条件语句)
      • 一旦文件流打开,会保持与对应文件的关联,对已打开文件流调用open会失败,会导致failbit被置位
      • 将文件流关联到另外一个文件,必须首先关闭已经关联的文件
  • 自动构造和析构

    • 当一个fstream对象离开其作用域时,与之关联的文件会自动关闭
    • 当一个fstream对象被销毁时,close会自动被调用

8.2.2 文件模式

文件模式
in以读的方式打开
out以写的方式打开
app每次写操作前均定位到文件末尾
ate打开文件后立即定位到文件末尾
trunc截断文件
binary以二进制方式进行IO
  • out: ofstream fstream

  • in: ifstream fstream

  • 只有out才可设定trunc

  • 只要没设trunc就可设定app,app即使没显式指定out,文件也以输出方式打开

  • 默认情况下,即使没指定trunc,以out打开i的文件也会被截断

  • ate和binary模式可用于任何类型的文件流对象,可与其他任何文件模式组合使用

  • ifstream默认以in模式打开;ofstream文件默认以out模式打开;与fstream关联文件默认以in和out模式打开

  • 以out模式打开文件会丢弃已有数据

    • 默认情况打开ofstream文件内容会被丢弃,阻止文件清空的方式是同时指定app模式或指定in模式
  • 每次调用open时都会确定文件模式

    • 对于给定流每次打开文件,都可以改变文件模式
    • out模式意味着同时使用trunc模式
    • 每次打开文件时都设置文件模式(显式设置/隐式设置/未指定为默认值)

8.3 string流

  • sstream头文件
    • istringstream从string读取数据
    • ostringstream向string写入数据
    • stringstream可读写string数据
  • sstream继承自iostream定义的类型
stringstream特有的操作
sstream strmstrm是一个未绑定的stringstream对象
sstream strm(s)strm是一个sstream对象,保存string s的一个拷贝。此析构函数是explicit
strm.str()返回strm所保存的string的拷贝
strm.str(s)string s拷贝到strm中,返回void

8.3.1 使用istringstream

  • 用getline从标准输入读取整行记录
  • 将一个istringstream与刚读取的文本进行绑定,在istringstream上使用输入运算符来读取当前记录中的每一个元素

8.3.2 使用ostringstream

  • 逐步构造输出,最后一起打印

小结

  • c++使用标准库类来处理面向流的输入和输出
    • iostream处理控制台IO
    • fstream处理命名文件IO
    • stringstream完成内存string的IO
  • fstream和stringstream继承自iostream
  • 每个io对象都维护一组条件状态,指出对象是否可进行io操作

术语表

  • 条件状态 可被任何流类使用的一组标志和函数,用来指出给定流是否可用
  • 文件模式 fstream定义标志,打开文件时指定,用来控制文件如何被使用
  • 继承 程序设计功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值