概述
C++语言与C语言一样,语言本身并不提供输入输出的支持,它们实现输入输出都是通过标准库来完成的。C语言的标准库提供一系列可以用来实现输入输出的函数,C++标准库则提供一系列类和对象来完成输入输出的功能,并且提供了流的概念,标准库中的IO类都是流概念的类。C++标准库中80%的内容属于STL,而IO库并不属于这80%。IO库体现的是面向对象的思想,但是有可能IO类也是基于模板实现的。
IOStreams基本概念
C++ IO由流(一种特殊的类的对象)完成,所谓的流是指按时间顺序生成的字符序列。按照面向对象的思想,流是由某个类别(类)定义出来的具有特定性质的对象。输出操作被定义为数据流入stream,输入操作被定义为数据流出stream。比较基础的类为istream类和ostream类,分别表示输入流和输出流。
全局性的stream对象
IOStream程序库定义了数个型别为istream和ostream的全局对象,它们对应于标准的IO通道(channels),分别是cout,cin,clog,cerr。可以使用重定向的机制使不同的全局对象指向不同的位置。
Stream操作符
利用操作符重载的机制,stream类可以将<<和>>这两个移位操作符重载为负责输入输出的操作符。
操控器
控制stream类进行某些操作,如endl。将std::endl赋给输出流会打印’ ’,同时利用flush来刷新缓冲区。还有std:ends等。
标准库的头文件组织以及继承关系
IO库由三个头文件组成定义,分别是iostream,fstream,sstream。Iostream中定义读写控制窗口的类型,fstream中定义读写已命名文件的类型,而sstream中定义读写内存中string对象的类型。fstream和sstream中定义的每种类型都是从iostream头文件中定义的相关类型中派生来的。
头文件 类型
iostream istream:从流中读取
ostream: 写到流中去
iostream:对流进行读写
fstream ifstream:对文件进行读
ofstream:对文件进行写
fstream:对文件进行读写
sstream istringstream:从string对象进行读取
ostringstream:读string对象写
stringstream:对string对象进行读写
条件状态(流状态)
输入输出流有状态,最简单的检查状态的方法是检查状态的真值。当输入或者输出流有错误时,流为错误状态。此时if(cin)为false,否则为if(cin)为true。
IO标准库管理一系列函数和条件状态(condition state)成员,用来标记给定的IO对象是否处于可用状态,或者碰到了哪些特定的错误。下面是标准库定义的一组函数和标记,提供访问和操纵流状态的手段。
strm:iostate:机器相关的整型名,由各个iostream类定义,用来定义条件状态,每个iostream类都有一个此类型的状态成员,用来标记流状态,它是以二进制位的形式存在的,使用clear和setstate进行管理。strm:badbit,strm:failbit,strm:eofbit,都是strm:iostate类型的值,用来标志特定的内容。标准库同时提供了一系列管理流状态的函数,根据条件状态的不同返回不同的结果或者来设置流状态。如s.eof(),s.fail(),s.bad(),s.good()等。一个使用状态类的例子:
int ival;
while(cin>>ival,!cin.eof())
{
if(cin.bad())
throw runtime_error(“IO stream corrupted”);
if(cin.fail())
{
cerr<<”bad data,try again”;
cin.clear(istream:failbit);
continue;
}
}
输出缓冲区的管理
每个IO对象管理一个缓冲区,用来存储程序读写的数据。缓冲区被刷新意味着缓冲区的内容被写入到真实的输出设备或者文件。刷新缓冲区有5种方式,两种默认的被动方式,三种主动的方式。默认的方式是程序正常退出时,以及缓冲区满时。主动的方式是使用操纵符,如endl,ends,flush等。使用unitbuf开始,则输出时每个输出完毕都刷新,使用nounitbuf结束。这个方式相当于设置流的状态。第三种主动方式是使用tie将输入输出流进行绑定。Cout和cin被绑定了。这样每次输入时都使得cout的缓冲区被刷新。建立绑定和解绑定方式为:cin.tie(&cout),cin.tie(0)。绑定函数为流的成员函数。