为了支持不同种类的IO处理操作,除istream和ostream之外,标准库还定义了一些其他的IO类型,分别定义在三个独立的头文件中:
- iostream定义了用于读写流的基本类型
- fstream定义了续写命名文件的类型
- sstream定义了读写内存string对象类型
为了支持使用宽字符的语言,标准库定义了一组类型和对象来操纵wchar_t类型的数据,以W开始:
wcin->cin
wcout->cout
wcerr->cerr
他们定义在同一个头文件中,例如,fstream定义了ifstream和wifstream类型。
IO类型间的关系
标准库使我们可以忽略不同类型间的差异,是通过继承机制实现的。通常我们可以将一个继承类的对象当做其基类的对象来使用。
例如:
ifstream和istringstream都继承自istream,所以我们可以像使用istream对象一样使用二者的对象。
例如:
可以对ifstream或者istringstream对象调用getline,也可以用>>从一个istream或istringstream对象中读取数据。
IO对象没有拷贝或者赋值操作
ofstream out1,out2;
out1=out2;//错误,不能赋值
ofstream print(ofstream);//错误,不能初始化ofstream参数
out2=print(out2);//错误,不能拷贝流对象
不能将形参或者返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。
IO流的状态
确定一个流对象的装套的最简单方法是将它当做一个条件来使用
while(cin>>word)
- 查询流状态
管理条件状态
例程:
#include<iostream>
#include<stdexcept>
using namespace std;
istream & f(istream &in)
{
int v;
while (in >> v, !in.eof())
{
if (in.bad())
throw runtime_error("IO流错误");
if (in.fail())
{
cerr << "数据错误,请重试" << endl;
in.clear();
in.ignore(100,'\n');
continue;
}
cout << v << endl;
}
in.clear();
return in;
}
int main()
{
cout << "请输入一些整数,以CTRL+Z结束" << endl;
f(cin);
return 0;
}
运行结果:
管理输出缓冲
刷新输出缓冲区的操作符:
- endl完成换行并刷新
- ends向缓冲区插入一个空字符,然后刷新
- flush刷新但不输出任何额外字符
unitbuf每次输出后刷新缓冲区
cout<<unitbuf
nounitbuf重置流
cout<<nounitbuf//回到正常缓冲方式
关联输入和输出流
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。