数据输入和输出过程也是数据传输的过程。数据就像流水一样从一个地方流动到另一个地方,因此,在C++中将此过程称为“流(stream)"。
在C++的标准库中,将用于进行数据输入输出的类统称为”流类“。cin是流类istream的对象,cout是流类ostream的对象。要使用流类,需要在程序中包含iostream头文件。
C++中常用的几个流类及其2相互关系:
图1中的箭头代表派生类。ios是抽象基类,它派生出istream和ostream。istream和ostream又共同派生出了iostream类。
为了避免多继承的二义性,从ios派生出istream和ostream时,均使用virtual关键字(虚继承)。
istream是用于输入的流类,cin就是该类的对象。
ostream是用于输出的流类,cout就是该类的对象。
ifstream是用于从文件读取数据的类。
ofstream是用于向文件写入数据的类。
iostream是既能用于输入,又能用于输出的类。
fstream是既能从文件读取数据,又能向文件写入数据的类。
标准流对象
iostream头文件中定义了四个标准流对象,它们是cin、cout、cerr和clog。
cin对应于标准输入流,用于从键盘读取数据,也可以被重定向为从文件中读取数据。
cout对应于标准输出流,用于向屏幕输出数据,也可以被重定向为向文件写入数据。
clog对应于标准错误输出流,用于向屏幕输出错误信息,不能被重定向。
cerr和clog的区别在于:cerr不适用缓冲区,直接向显示器输出信息;而输出到clog中的信息会先被存放到缓冲区,缓冲区满或者刷新时才输出到屏幕。
ostream类的无参构造函数和复制构造函数都是私有的,因此在程序中一般无法定义ostream类的对象,唯一能用的ostream类的对象就是cout。
cout可以被重定向,而cerr不能。所谓重定向,就是将输入的源或输出的目的地改变。例如,cout本来是输出到屏幕的,但是经过重定向,本该输出到屏幕上的东西就可以被输出到文件中。
例如:
#include
using namespace std;
int main()
{
int x,y;
cin >> x >> y;
freopen("test.txt", "w", stdout); //将标准输出重定向到 test.txt文件
if( y == 0 ) //除数为0则输出错误信息
cerr << "error." << endl;
else
cout << x /y ;
return 0;
}
其中,freopen是个标准库函数,第二个参数w代表写模式,第三个参数代表标准输出。该语句的作用是将标准输出重定向为test.txt文件。重定向之后,所有对cout的输出都不再出现在屏幕上,而是在test.txt文件中。
cin也可以被重定向,如果在程序中加入
freopen("input.dat", "r", stdin);
第二个参数r代表读入方式,第三个参数stdin代表输入。执行此语句后,cin就不再从键盘读入数据,而是从input.dat文件中读入数据。
使用流操作算子
C++中常用的输入流操纵算子如表1所示,它们都是在头文件iomanip中定义的,要使用这些流操纵算子,必须包含该头文件。
note:"流操纵算子"一栏中的*不是算子的一部分,星号表示在没有使用任何算子的情况下,就等效于使用了该算子。例如,在默认情况下,整数是十进制形式输出的,等效于使用了dec算子。
流操作算子的用法
使用这些算子的方法是将算子用<<和cout连用。例如
cout<
这条语句的作用是指定以十六进制形式输出后面两个数,因此输出结果是:
c,18
setiosflags()算子
setiosflags()算子实际上是一个函数库,它以一些标志作为参数,这些标志可以是在iostream头文件中定义的以下几种取值,它们的含义和同名算子一样。
这些标志实际上都是仅有某比特位为1,而其他比特位都为0的整数。
多个标志可以用|运算符连接,表示同时设置。例如:
cout << setiosflags(ios::scientific|ios::showpos) << 12.34;
如果两个相互矛盾的标志同时被设置,如先设置setiosflags(ios::fixed),然后设置setiosflags(ios::scientific),那么结果可能就是两个标志都不起作用。因此,在设置了某标志,又要设置其他与之矛盾的标志时,就应该用resetiosflags清除原先的标志。例如下面的三条语句:
cout << setiosflags(ios::fixed) << 12.34 << endl;
cout << resetiosflags(ios::fixed) << setiosflags(ios::scientific | ios::showpos) << 12.34 << endl;
cout << resetiosflags(ios::showpos) << 12.34 << endl; //清除要输出正号的标志
输出结果是:
12.340000
+1.234000e+001
1.234000e+001
需要注意的是,setw()算子所起的作用是一次性的,即之影响下一次输出,每次需要指定输出宽度时都要使用setw()。因可以看到,第9)行的输出因为没有使用setw(),输出宽度就不再是前面所指定的12个字符。
在读入字符串时,setw()还能影响cin的行为,例如下面的程序:
#include
#include
using namespace std;
int main()
{
string s1, s2;
cin >> setw(4) >> s1 >> setw(3) >> s2;
cout << s1 << "," << s2 << endl;
return 0;
}
输入:
1234567890↙
程序的输出结果是:
1234,567
说明setw(4)使得读入s1时,只读入4个字符串,其后的setw(3)使得读入s2时只读入3个字符。
setw()用于cin时,同时只影响下一次的输入。
调用cout的成员函数
ostream类有一些成员函数,通过cout调用它们也能用于控制输出的格式,其作用和流操纵算子相同。
这些成员函数的用法十分简单,如:
cout.setf(ios::scientific);
cout.precision(8);
cout << 12.23 << endl;
输出结果是:
1.22300000e+001
文章内容来自于http://c.biancheng.net/view/275.html