iostream定义了用于读写流的基本对象
fstream定义了读写命名文件的类型
sstream定义了读写内存string对象的类型
cin>>n;//键盘输入n,利用右移运算符>>,cin读取n的值,然后存储在计算机内存中
cout<
IO类型间的关系:
标准库可以使我们忽略不同类型的流之间的差异,是通过继承机制去实现的。类型ifstream和istringstream都是继承自istream,也就是说我们是如何使用cin的,就同样可以使用这些类型的对象。
IO类型的对象不能进行拷贝或者赋值,所以对IO操作的函数通常是引用方式传递和返回流的。
由于读写一个IO对象会改变其状态,所以传递和引用不能是const。
IO操作一个与生俱来的问题时可能发生错误,有些错误可以修复,而其他错误则发生在系统深处,已经超过了应用程序可以修正的范围。
下表中的IO类定义的一些函数和标志 ,可以帮助我们访问和操纵流的条件状态:
确定一个流对象的状态的最简单的方法是将它作为一个条件使用:while(cin>>word);
查询流的状态:
IO库定义了一个与机器无关的iostate类型,它提供了表达流的完整功能。badbit、failbit、eofbit用来检测流的状态。标准库还定义了一组函数来查询这些标志位的状态,如eof,fail等等。
#include
#include
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 << "数据错误,请重试:";//立即刷新缓冲区
in.clear();//清除对象in
in.ignore(100,'\n');//把\n之前的100个数据消除
//break;
continue;
}
cout << v << endl;
}
in.clear();
return in;
}
int main(void)
{
system("color 03");
cout << "请输入一些整数,按Ctrl+Z结束:";
f(cin);
system("pause");
}
遇到了文件结束符标志Ctrl+z,或者遇到了IO流错误,或者读入了无效数据。
缓冲机制的优点:操作系统可以把程序的多个输出操作合成==单一的系统级写操作==,这样就可以得到很大的性能提升了。
导致缓冲刷新的原因:
1、程序正常退出,作为main函数的return操作的一部分,缓冲刷新被执行
2、缓冲区满时,需要刷新缓冲,而后的新数据才能继续写入缓冲区
3、使用endl来显式刷新缓冲区
4、使用操纵符unitbuf设置流的内部状态,来清空缓冲区。默认情况下,对cerr是设置unitbuf的,所以写到cerr的内容都是立即被刷新的
5、一个输出流被关联到另一个流。读写被关联的流,关联的流会被刷新。默认情况下,cin和cerr都关联到cout,因此读cin或者cerr都会导致cout的缓冲区被刷新。
刷新输出缓冲区:
endl:先换行,然后再刷新缓冲区
flush:直接刷新缓冲区,不输出任何字符
ends:向缓冲区插入一个空字符,然后在刷新缓冲区
unitbuf操纵符:
如果每次输出操作后都刷新缓冲区,我们可以使用unitbuf操作符,作用是每次系统级写操作之后都进行一次flush操作。nounitbuf操作符则重置流,使其恢复使用正常的系统管理的缓冲区机制。
关联输入和输出流:
一个输入流关联到一个输出流,任何试图从输入流读取数据的操作都会刷新关联的输出流。
标准cout和cin关联在一起,cin>>ival;会导致cout的缓冲区被刷新。
每个流最多关联到一个流,但是多个流就可以关联到ostream。