C++ Primer笔记(八)
IO库
IO类
iostream
定义了用于读写流的基本类型,fstream
定义了读写命名文件的类型,sstream
定义了读写内存string对象的类型
为了支持使用宽字符,定义了一组类型和对象来操作wchar_t
类型,以一个w开头
- 概念上,设备类型和字符大小不会影响我们要执行的IO操作,这是通过继承实现的,如
ifstream
和istringstream
都继承自istream
,因此我们是如何使用cin,就同样可以使用这些类型的对象 - IO对象是没有拷贝和赋值的,所以不能将形参和返回类型设置为流类型,只能设置为引用类型且不能是const,因为读写一个流会改变其状态
- 定义了一些函数和标志来访问和操作流的条件状态,一旦一个流发生错误,则其上后续的IO操作都会失败,无错时才能从它读取数据,向它写入数据,所以在操作流时应当检查它是否处于良好状态
while(cin>>x)
- 查询流的状态,iostate类型的对象表示特定的IO条件,与位运算符一起使用来检测或者设置多个标志位。所以标准库定义了一系列函数来查询这些标志位的状态,good在所有错误位未置位的情况下返回true,而bad,fail和eof在对应错误位被置位时返回true
- 流对象的
rdstate()
成员返回一个iostate
值来表示当前状态,而clear()
不带参数的版本清除所有标志位,带参数的版本表示流的新状态。setstate()
将输入流置为原有状态 ,流的状态为0表示未发生错误。
管理输出缓冲
- 由于设备的写操作可能很耗时,所以操作系统可以将多个输出操作合成单一的系统级写操作,所以设置了缓冲区,缓冲区在刷新时才会真正写出,缓冲区刷新有以下几种情况
- 程序正常结束
- 缓冲区满
- 操纵符endl显式刷新
- 在每个输出操作之后,可以用unitbuf设置流的内部状态来清空缓冲区
- 读写被关联的流时,关联到的流的缓冲区都会刷新,如读写cin cerr都会刷新cout
- endl可以刷新缓冲区,而flush和ends也可以刷新缓冲区,flush不输出任何额外字符,ends插入一个空字符
- 如果想在每次输出操作都刷新缓冲区,可以使用unitbuf
- tie有两个重载的版本,一个不带参数,如果已经关联到一个输出流,返回指向输出流的指针,否则返回空指针。第二个版本接受一个指向
ostream
的指针,is.tie(os)
将is流关联至os流
文件输入输出
- 头文件
fstream
定义了三个类型支持文件IO ifstream从文件读数据,ofstream向文件写入数据,fstream读写给定文件 -
ifstream in(filename)
打开给定文件构造输入流,ofstream out
构造输出流 - 通过open方法打开指定文件,close关闭文件,需要注意的是,对一个已经打开的文件流调用open会失败,如果调用失败,failbit会被置位以供检查,
- 文件输入流离开作用域时,与之关联的文件会自动关闭,对象自动销毁
- 默认情况下,打开一个ofstream,打开是out+trunc模式,文件的内容会被丢弃,需要同时指定app模式
ofstream app2("file1",ofstream::out|ofstream::app)
就可以在写入时定位到文件末尾 - 每次调用open时都会确定文件模式,
string流
- sstream定义了三个类型支持内存IO,
istringstream ostringstream iostringstream
而这三个类型.str()方法返回类型所保存的string的拷贝,str(s)将s字符串拷贝到对象中,同样这三个对象也可以重载iostream的操作 - 流替代的是cin,从流代表的文件或者string种输入到程序变量中
cin>>string
按单词输入,getline(cin, string)
按一整行输入