文章目录
第Ⅱ部分 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:iostate | iostate是一种机器无关的类型,提供了表达条件状态的完整功能 |
strm:badbit | strm:badbit用来指出流已经崩溃 |
strm:failbit | strm:failbit用来指出一个IO操作失败了 |
strm:eofbit | strm:eofbit用来指出流到达了文件结束 |
strm:goodbit | strm:goodbit用来指出流未处于错误状态 此值保证为零 |
s.eof() | 若流s 的eofbit 置位,则返回true |
s.fail() | 若流s 的failbit /badbit 置位,则返回true |
s.bad() | 若流s 的badbit 置位,则返回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被置位
- 将文件流关联到另外一个文件,必须首先关闭已经关联的文件
- 定义了一个空文件流,可以调用open将其与文件关联起来
-
自动构造和析构
- 当一个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 strm | strm是一个未绑定的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定义标志,打开文件时指定,用来控制文件如何被使用
- 继承 程序设计功能