C++ Primer笔记(八)

IO库

IO类

iostream定义了用于读写流的基本类型,fstream定义了读写命名文件的类型,sstream定义了读写内存string对象的类型
为了支持使用宽字符,定义了一组类型和对象来操作wchar_t类型,以一个w开头

  1. 概念上,设备类型和字符大小不会影响我们要执行的IO操作,这是通过继承实现的,如ifstreamistringstream都继承自istream,因此我们是如何使用cin,就同样可以使用这些类型的对象
  2. IO对象是没有拷贝和赋值的,所以不能将形参和返回类型设置为流类型,只能设置为引用类型且不能是const,因为读写一个流会改变其状态
  3. 定义了一些函数和标志来访问和操作流的条件状态,一旦一个流发生错误,则其上后续的IO操作都会失败,无错时才能从它读取数据,向它写入数据,所以在操作流时应当检查它是否处于良好状态while(cin>>x)
  4. 查询流的状态,iostate类型的对象表示特定的IO条件,与位运算符一起使用来检测或者设置多个标志位。所以标准库定义了一系列函数来查询这些标志位的状态,good在所有错误位未置位的情况下返回true,而bad,fail和eof在对应错误位被置位时返回true
  5. 流对象的rdstate()成员返回一个iostate值来表示当前状态,而clear()不带参数的版本清除所有标志位,带参数的版本表示流的新状态。setstate()将输入流置为原有状态 ,流的状态为0表示未发生错误。

管理输出缓冲

  1. 由于设备的写操作可能很耗时,所以操作系统可以将多个输出操作合成单一的系统级写操作,所以设置了缓冲区,缓冲区在刷新时才会真正写出,缓冲区刷新有以下几种情况
  • 程序正常结束
  • 缓冲区满
  • 操纵符endl显式刷新
  • 在每个输出操作之后,可以用unitbuf设置流的内部状态来清空缓冲区
  • 读写被关联的流时,关联到的流的缓冲区都会刷新,如读写cin cerr都会刷新cout
  1. endl可以刷新缓冲区,而flush和ends也可以刷新缓冲区,flush不输出任何额外字符,ends插入一个空字符
  2. 如果想在每次输出操作都刷新缓冲区,可以使用unitbuf
  3. tie有两个重载的版本,一个不带参数,如果已经关联到一个输出流,返回指向输出流的指针,否则返回空指针。第二个版本接受一个指向ostream的指针,is.tie(os)将is流关联至os流

文件输入输出

  1. 头文件fstream定义了三个类型支持文件IO ifstream从文件读数据,ofstream向文件写入数据,fstream读写给定文件
  2. ifstream in(filename)打开给定文件构造输入流,ofstream out构造输出流
  3. 通过open方法打开指定文件,close关闭文件,需要注意的是,对一个已经打开的文件流调用open会失败,如果调用失败,failbit会被置位以供检查,
  4. 文件输入流离开作用域时,与之关联的文件会自动关闭,对象自动销毁
    C++ Primer笔记(八)
  5. 默认情况下,打开一个ofstream,打开是out+trunc模式,文件的内容会被丢弃,需要同时指定app模式
    ofstream app2("file1",ofstream::out|ofstream::app)就可以在写入时定位到文件末尾
  6. 每次调用open时都会确定文件模式,

string流

  1. sstream定义了三个类型支持内存IO,istringstream ostringstream iostringstream 而这三个类型.str()方法返回类型所保存的string的拷贝,str(s)将s字符串拷贝到对象中,同样这三个对象也可以重载iostream的操作
  2. 流替代的是cin,从流代表的文件或者string种输入到程序变量中cin>>string按单词输入,getline(cin, string)按一整行输入