c++中定义的标准输入输出流是istream和ostream,他们是iostream类的父类,而cin是istream的对象,cout是ostream的对象。头文件fstream(对文件操作的流)包含了ifstream和ofstream,头文件sstream(对字符串操作的流)包含了istringstream和ostringstream,这些类都是继承自istream和ostream的。所以iostream具有的一些操作它们都有。在函数参数传递的时候,根据父类的引用可以指向子类对象的原则,所有要求传入iostream类的对象的函数都可以传入fstream和sstream的对象。下面来张图,展示它们的具体继承关系。

标准输入输出流的使用

接着就通过代码来看下,涉及到流操作的一些函数的使用。

#include <iostream>

using namespace std;

istream & get(istream & in);

int main()
{
	get(cin);
	double d;
	cin>>d;
	cout<<d<<endl;
	return 0;
}

//IO对象不可以赋值,所以这里只能传入引用类型或者是指针,返回值也是同样的道理
istream & get(istream & in)
{
	int i;
	//in>>i返回错误的情况是系统级的故障,读到了非法字符或者是遇到了文件尾,我们也可以使用while(in>>i)
	//当遇到了文件尾的时候eof()函数返回真,在win32下我们可以使用ctrl+z来模拟文件尾
	while(in>>i,!in.eof())
	{
		//bad()函数如果返回的是真,代表的是遇到了系统级的故障
		if(in.bad())
		{
			throw runtime_error("IO stream corrupted");
		}
		//一般我们输入非法字符的时候fail()函数返回的就是真值
		if(in.fail())
		{
			//cerr代表的是标准错误
			cerr<<"bad data,try again"<<endl;
			//将failbit位置为有效状态,如果clear里边没有参数的话,是将所有的状态位都置为有效状态
			in.clear(istream::failbit);
			//ignore作用是清除字符,没有参数的时候就是清除下一个字符,就是cin将要读的那个字符 in.ignore();
			//这个函数可以传入俩个参数,第一个参数代表清除多少个字符,第二个参数清除字符直到遇到第二个参数代表的字符
			//我们可以把第一个参数设置的很大,这样的话它就会清空字符直到遇到第二个参数的字符
			in.ignore(1024,'\n');
			continue;
		}
		cout<<i<<endl;
	}
	in.clear(istream::eofbit);
	return in;
}