C++ Primer记录_第八章

第8章 IO库

  • C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO。这些类型支持从设备读取数据、向设备写入数据的IO操作,设备可以是文件、控制台窗口等。
  • IO库设施:
    • istream(输入流)类型,提供输入操作。
    • ostream(输出流)类型,提供输出操作。
    • cin,一个istream对象,从标准输入读取数据。
    • cout,一个ostream对象,向标准输出写入数据。
    • cerr,一个ostream对象,通常用于输出程序错误消息,写入到标准错误。
    • >>运算符,用来从一个istream对象读取输入数据。
    • <<运算符,用来向一个ostream对象写入输出数据。
    • getline函数,从一个给定的istream读取一行数据,存入一个给定的string对象中。

8.1 IO类

  • 标准库还定义了其他一些IO类型,分别在三个独立的头文件中:
    1. iostream定义了用于读写流的基本类型。
    2. fstream定义了读写命名文件的类型。
    3. sstream定义了读写内存string对象的类型。
  • 概念上,设备类型和字符大小都不会影响我们要执行的IO操作。
  • 标准库使我们能忽略这些不同类型的流之间的差异,这是通过继承机制实现的。

8.1.1 IO对象无拷贝或赋值

  • 我们不能拷贝或对IO对象赋值,由于不能拷贝IO对象,因此我们也不能将形参或返回类型设置为流类型。
ofstream out1, out2;
out1 = out2;             //错误:不能对流对象赋值
ofstream print(ofstram); //错误:不能初始化ofstream参数
out2 = print(out2);      //错误:不能拷贝流对象

8.1.2 条件状态

  • IO操作的问题是可能发生错误。
  • IO类所定义的一些函数和标志,可以帮助我们访问和操纵流的条件状态
函数与标记用法
strm::iostatestrm是一种IO类型,iostate是一种机器相关的类型,提供了表达条件状态的完整功能
strm::badbitstrm::badbit用来指出流已崩溃
strm::failbitstrm::failbit用来指出一个IO操作失败了
strm::eofbitstrm::eofbit用来指出流到达了文件结束
s.eof()若流s的eofbit置位,则返回true
s.fail()若流s的failbit或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

8.1.3 管理输出缓冲

  • 每个输出流都管理一个缓冲区,用来保存程序读写的数据。
  • 导致缓冲刷新的原因:
    • 程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行。
    • 缓冲区满时,需要刷新缓冲,而后新的数据才能继续写入缓冲区。
    • 我们可以使用操纵符如endl来显式刷新缓冲区。
    • 在每个输出操作之后,我们可以用操纵符unitbuf设置流的内部状态,来清空缓冲区,默认情况下,对cerr是设置unitbuf的,因此写到cerr的内容都是立即刷新的。
    • 一个输出流可能被关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如,默认情况下,cin和cerr都关联到cout。因此,读cin或写cerr都会导致cout的缓冲区被刷新。
  • 刷新输出缓冲区
cout << "hi!" << endl;  //输出hi和一个换行,然后刷新缓冲区
cout << "hi!" << flush; //输出hi,然后刷新缓冲区,不附加任何额外字符
cout << "hi!" << ends;  //输出hi和一个空字符,然后刷新缓冲区
  • 如果想在每次输出操作后都刷新缓冲区,我们可以使用unitbuf操纵符。
cout << unitbuf;   //所有捡出操作后都会立即刷新缓冲区
cout << nounitbuf; //回到正常的缓冲方式
  • 当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。

8.2 文件输入输出

  • 头文件fstream定义了三个类型来支持文件IO:
    1. ifstream从一个给定文件读取数据。
    2. ofstream向一个给定文件写入数据。
    3. fstream可以读写给定文件。
函数与标记用法
fstream fstrm;创建一个未绑定的文件流,fstream是头文件fstream中定义的一个类型
fstream fstrm(s);创建一个fstream,并打开名为s的文件
fstream fstrm(s,mode)与前一个构造函数类似,但按指定mode打开文件
fstrm.open(s)打开名为s的文件,并将文件与fstrm绑定
fstrm.close()关闭与fstrm绑定的文件,返回void
fstrm.is_open()返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭

8.2.1 使用文件流对象

  • 当我们想要读写一个文件时,可以定义一个文件流对象,并将对象与文件关联起来。
ifstream in(ifile); //构造一个ifstream并打开给定文件
ofstream out;       //输出文件流并关联到任何文件
  • 接受一个iostream类型引用(或指针)参数的函数,可以用一个对应的fstream(或sstream)类型来调用。
  • 成员函数open和close
ifstream in(ifile);        //构筑一个ifstream并打开给定文件
ofstream out;              //输出文件流未与任何文件相关联
out.open(ifile + ".copy"); //打开指定文件
if (out)                   //检查open是否成功
in.close();           //关闭文件
in.open(ifile + "2"); //打开另一个文件
  • 自动构造和析构。

8.2.2 文件模式

  • 每个流都有一个关联的文件模式,用来指出如何使用文件。
文件模式用法
in以读方式打开
out以写方式打开
app每次写操作前均定位到文件末尾
ate打开文件后立即定位到文件末尾
trunc截断文件
binary以二进制方式进行IO
  • 指定文件模式有如下限制:
    • 只可以对ofstream或fstream对象设定out模式。
    • 只可以对ifstream或fstream对象设定in模式。
    • 只有当out也被设定时才可设定trunc模式。
    • 只要trunc没被设定,就可以设定app模式。在app模式下,即使没有显式指定 out模式,文件也总是以输出方式被打开。
    • 默认情况下,即使我们没有指定trunc, 以out模式打开的文件也会被截断。为了保留以out模式打开的文件的内容,我们必须同时指定app模式,这样只会将数据追加写到文件末尾;或者同时指定in模式,即打开文件同时进行读写操作。
    • ate和binary模式可用于任何类型的文件流对象,且可以与其他任何文件模式组合使用。
  • 以out模式打开文件会丢弃已有数据。
//在这几条语句中,file1都被截断
ofstream out("file1");                                   //隐含以输出模式打开文件并截断文件
ofstream out2("file1", ofstream::out);                   //隐含地截断文件
ofstream out2("file1", ofstream::out | ofstream::trunc); //为了保留文件内容,我们必须显式指定app模式
//为了保留文件内容,我们必须显式指定app模式
ofstream app("file2", ofstream::app); //隐含为输出模式
ofstream app2("file2", ofstream::out | ofstream::app);
  • 每次调用open时都会确定文件模式。
ofstream out;                        //未指定文件打开模式
out.open("scratchpad");              //模式隐含设置为输出和截断
out.close();                         //关闭out, 以便我们将其用于其他文件
out.open("precious", ofstream::app); //模式为榆出和追加
out.close();

8.3 string流

  • sstream头文件定义了三个类型来支持内存IO:
    1. istringstream从string读取数据。
    2. ostringstream向string写入数据。
    3. stringstream既可从string读数据也可向string写数据。
函数与标记用法
sstream strm;strm是一个未绑定的stringstram对象。sstream是头文件sstream中定义的一个类型。
sstream strm(s);strm是一个sstream对象,保存strings的一个拷贝,此构造函数是explicit的。
strm.str()返回strm所保存的string的拷贝。
strm.str(s)将string s拷贝到strm中,返回void。

8.3.1 使用istringstream

  • 当某些工作是对整行文本进行处理,而其他一些工作是处理行内的单个单词时,通常可以使用istringstream。

8.3.2 使用ostringstream

  • 当我们逐步构造输出,希望最后一起打印时,ostringstream是很有用的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Flame老唐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值