[C++ Primer Note7] IO库

C++语言不直接处理输入输出,而是通过一组定义在标准库中的类型来处理IO。这些类型支持从设备读取数据,向设备写入数据的IO操作,设备可以是文件,控制台窗口等等

  1. 我们前文已经提到过很多IO库设施,这里再做一个简单的回顾:
  • istream(输入流)类型,提供输入操作
  • ostream(输出流)类型,提供输出操作
  • cin,一个istream对象,从标准输入读取数据
  • cout,一个ostream对象,向标准输出写入数据
  • cerr,一个ostream对象,通常用于输出错误信息,写入到标准错误
  • >>运算符,用来从一个istream对象读取输入数据
  • <<运算符,用来向一个ostream对象写入输出数据
  • getline函数,从一个给定的istream读取一行数据,存入一个string对象中
  1. 除了定义了用于读写流的基本类型的iostream头文件外,fstream定义了读写命名文件的类型,sstream定义了读写内存string对象的类型
  2. ifstream和istringstream都继承自istream(对于输出类型也一样),我们可以像使用istream对象一样来使用前两者。
  3. IO对象不能被拷贝,进行IO操作的函数通常以引用方式传递和返回流,读写一个IO对象会改变其状态,所以引用不能是const的
  4. IO类定义了一些函数和标志来帮助我们访问和操纵流的条件状态,包括状态的查询和设置,此处不赘述。
  5. 每个输出流都管理一个缓冲区,用来保存读写的数据,从而将程序的多个输出操作组合成单一的系统级写操作。导致缓冲刷新的原因有很多:
  • 程序正常结束(main函数return)
  • 缓冲区满
  • 使用操纵符如endl来显式刷新缓冲区
  • 在每个输出操作之后,我们可以用操纵符unitbuf设置流的内部状态来清空缓冲区。
  • 一个输出流可能被关联(tie)到另一个流。当读写主动关联的流时,被关联到的流的缓冲区会被刷新。默认情况下,cin和cerr关联到cout。读cin或写cerr会导致cout的缓冲区被刷新。
  1. IO库还有两个类似endl的操纵符:flushends,flush刷新缓冲区不输出额外的字符;ends向缓冲区插入一个空字符,然后刷新缓冲区。
  2. 如果想在每次输出操作后都刷新缓冲区,我们可以使用unitbuf操纵。
    nounitbuf则重置流
    cout<
  1. 程序崩溃后,输出缓冲区是不会刷新的
  2. 当一个输入流关联一个输出流,任何试图从输入流读取数据的操作都会先刷新关联的输出流。标准库将cout和cin关联在一起,所以:
    cin>>val;

将导致cout的缓冲区被刷新,这对交互式系统而言有重要意义,因为用户输入提示会在读操作之前被打印出来。
11.关联操作通过tie函数实现,具体用法不赘述。每个流同时最多关联一个流,但多个流可以同时关联到同一个ostream

  1. 头文件fstream定义了三个类型来支持文件IO:ifstream从一个给定文件读取数据,ofstream向一个给定文件写入数据,以及fstream可以读写给定文件。这些类型提供的操作与我们之前使用过的对象cin和cout的操作一样,除此以外还增加了一些新的成员来管理与流关联的文件。
  2. 当我们想要读写一个文件时,可以定义一个文件流对象,并将对象与文件通过open成员函数关联起来。也可以在初始化时指定,此时open自动被调用。
    ifstream in(filename);
  1. 因为在要求使用基类对象的地方,我们可以用继承类型的对象代替。所以,接收一个iostream类型引用或指针参数的函数,可以用一个对应的fstream(sstream)类型来调用。
  2. 每个流都有一个关联的文件模式,用来指出如何使用文件(包括读,写,追加写入等),此处也不赘述。
  3. sstream头文件定义了三个类型来支持内存IO,istringstream从string读取数据,ostringstream向string写入数据,stringstream既可读也可写。这些类型在需要对string进行细致的控制的时候(比如制造格式输出)是很有用的,但大体来说使用频率低于前述两种流类型。

你可能感兴趣的:([C++ Primer Note7] IO库)