IO库
C++语言自己不直接处理输入和输出,而是通过一族定义在标准库中的类型来处理IO。这些类型支持从设备(文件、控制台、内存等)读写数据。
IO类
IO类型定义在三个头文件中:iostream、fstream、sstream。三种头文件针对的是三种不同的对象:流、文件、string。其中每个头文件都定义了多种类型,依次分别问:istream、ostream、iostream;iftream、ofstream、fstream;istringstream、wistringstream、ostringstream、wostringstream、stringstream、wstringstream。
1)通过继承机制,可以忽略不同类型之间的差异。
2)不能对IO对象进行拷贝和赋值。进行IO操作的函数通常以引用的方式传递和返回流。
3)读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的。
4)IO操作会产生一些错误,这些错误有些可恢复有些不能恢复。为此,IO类定义了一些函数和标志来检测和操纵流的状态。
//strm是一种IO类型
strm::iostate // iostate是一种机器相关的类型,提供了表达条件状态的完整功能
strm::badbit //用来指出流已经崩溃
strm::failbit //用来指出一个IO操作失败了
strm::eofbit //用来指出流达到了文件结束
strm::goodbit //用来指出流处于未出错状态,此时值为0
//s为流
s.eof() //若eofbit置位,返回true
s.fail() //若badbit或者failbit置位,返回true
s.bad() //若badbit置位,返回true
s.good() //若流s处于有效状态,返回true
s.clear() //对流的所有状态进行复位,流设置为有效状态
s.clear(flags)//对给出的标志位进行复位
s.setstate(flags)//对给出的标志位进行置位
s.rdstate()//返回当前流的状态
输出缓冲
每个输出流都管理一个缓冲区,用来保存程序读写的数据。缓冲机制的存在,使得操作系统可以将程序的多个输出操作组合成单一的系统级写操作以提升性能。缓冲区刷新即将数据真正写到输出设备或者文件,导致缓冲区刷新的原因有:
1)程序正常结束,作为main函数的return操作的一部分刷新缓冲区;
2)缓冲区满了会自动刷新;
3)使用操纵符如endl、flush、ends等来显式刷新;
4)在每个输出操作之后,可以使用操纵符unitbuf设置流的内部状态,来清空缓冲区;
5)一个输出流关联到另一个流时,当读写被关联的流时,关联到的流的缓冲区被刷新。
文件流
头文件fstream中定义了三种类型:ifstream支持从一个给定文件中读取数据,ofstream向一个给定文件中写入数据,fstream可以读写给定文件。注意,使用fstream时,如果向不存在的文件输出内容,不会自动创建文件!!!
fstream头文件中还增加了一些针对上述几种类型的操作:
//fstream是头文件fstream中定义的一个类型
fstream fstrm; //创建一个未绑定的文件流
fstream fstrm(s); // 创建一个fstream,打开名为s的文件。s可以是string类型或者一个指向C风格字符串的指针
fstream fstrm(s, mode); //按照指定mode打开文件
fstrm.open(s) //打开名为s的文件,并将文件与fstrm绑定。
fstrm.close() //关闭fstrm绑定的文件。
fstrm.is_open() //返回一个bool,指出与fstrm关联的文件是否成功打开且尚未关闭
文件模式
in //以读的方式打开
out //以写的方式打开
app //每次写操作前均定位到文件末尾
ate //打开文件口立即定位到文件末尾
trunc //截断文件
binary //以二进制的方式进行IO
string流
sstream头文件中定义了三种类型来支持内存IO:istringstream、ostringstream、stringstream。
sstream strm; // strm是一个未绑定的stringstream对象。
sstream strm(s); //strm是一个sstream的对象,保存string s的一个拷贝。
strm.str() //返回strm所保存的string的对象
strm.str(s) //将string s拷贝到strm中