11.3 输出流
C++ 的类 ostream 提供了格式化输出和无格式输出的功能。输出功能包括:用流插入运算符输出标准类型的数据;用成员函数 put 输出字符;成员函数 write 的无格式化输出(11.5节);输出十进制、八进制、十六进制格式的整数(11.6.1节);输出各种精度的浮点数(11.6.2节)、输出强制带有小数点的浮点数(11.7.2节)以及用科学计数法和定点计数法表示的浮点数(11.7.6节);输出在指定域宽内对齐的数据(11.7.3节);输出在域宽内用指定字符填充空位的数据(11.7.4节);输出科学计数法和十六进制计数法中的大写字母(11.7.7节)。
11.3.1 流插入运算符
流插入运算符(即重载的运算符<<)可实现流的输出。重载运算符<<是为了输出内部类型的数据项、字符中和指针值。11.9节要详细介绍如何用重载运算符<<输出用户自定义类型的数据项。
图11.3中的范例程序用一条流插入语句显示了输出的字符串。图 11.4 中的范例程序用多条流插入语句显示输出的字符串,该程序的运行结果与图11.3中程序的运行结果相同。
1 // Fig. 11.3: figll 03.cpp
2 // Outputting a string using stream insertion.
3 #include <iostream.h>
4
56 int main()
7 cout << "Welcome to C++!\n";
8
9 return O;
10 }
输出结果:
Welcome to C++!
图 11.3 用一条流插入语句输出字符串
1 // Fig. 11.4: figllO4.cpp
2 // Outputting a string using two stream insertions.
3 #include <iostream.h>
4
5 int main()
6{
7 cout << "Welcome to ";
8 cout << "C++!\n";
9
10 return 0;
11 }
输出结果:
Welcome to C++!
图 11.4 用两条流插入语句输出字符串
也可以用流操纵算子endl(行结束)实现转义序列\n(换行符)的功能(见图11.5)。流操纵算子endl发送一个换行符并刷新输出缓冲区(不管输出缓冲区是否已满都把输出缓冲区中的内容立即输出)。也可以用下面的语句刷新输出缓冲区:
cout << flush;
11.6 节要详细讨论流操纵算子。
1 // Fig. 11.5: fig11_05.cpp
2 // Using the endl stream manipulator.
3 #include <iostream.h>
4
5 int main{)
6 {
7 cout << "Welcome to ";
8 cout << "c++!';
9 cout << endl; // end line stream manipulator
10
11 return 0;
12 }
输出结果:
Welcome to C++!
图 11.5 使用流操纵算子 endl
流插入运算符还可以输出表达式的值(见图11.6)
1 // Fig. 11.6: fig11_O6.cpp
2 // Outputting expression values.
3 #include <iostream.h>
4
5 int main()
6 {
7 cout << "47 plus 53 is ";
8
9 // parentheses not needed; used for clarity
10 cout << ( 47 + 53 ); // expression
11 cout << endt;
12
13 return O;
14 }
输出结果:
47 plus 53 is 100
图 11.6 输出一个表达式的值
编程技巧 11.2
当输出表达式时,为防止表达式中的运算符与运算符<<之间存在运算符化先级问题,用括号将表达式括起来。
11.3.2 连续使用流插入/流读取运算符
重载的运算符<<和>>都可以在一条浯句中连续使用(见图11.7)。
1 file:// Fig.11.7: fig11_07.cpp
2 file:// Cascadlng the overlOadGd << OPeratOr.
3 #includc<iostream.h>
4
5 int main()
6 {
7 cout << "47 plus 53 is " << ( 47 + 53 ) << endl;
8
9 return O;
10 }
输出结果:
47 plus 53 is 100
图 11.7 连续使用重载运算符 <<
图中多次使用流插入运算符的语句等同于下面的语句:
((( cout << " 47 plus 53 is " ) << 47 + 53 ) << endl);
之所以可以使用这种写法,是因为重载的运算符<<返回了对其左操作数对象(即cout)的引用,因此最左边括号内的表达式:
( cout << " 47 plus 53 is " )
它输出一个指定的字符串,并返回对cout的引用,因而使中间括号内的表达式解释为:
( cout << ( 47 + 53 ) )
它输出整数值100,并返回对cout的引用。于是最右边括号内的表达式解释为:
cout << endl;
它输出一个换行符,刷新 cout 并返回对 cout 的引用。最后的返回结果未被使用。
11.3.3 输出 char*
类型的变量
C 语言式的I/O必须要提供数据类型信息。C++对此作了改进,能够自动判别数据类型。但是,C++中有时还得使用类型信息。例如,我们知道字符串是char*类型,假定需要输出其指针的值,即字符串中第一个字符的地址,但是重载运算符 << 输出的只是以空(null)字符结尾的char*类型的字符串,因此使用void*类型来完成上述需求(需要输出指针变量的地址时都可以使用void*类型)。
图11.8中的程序演示了如何输出char*类型的字符串及其地址,辅出的地址是用十六进制格式表示。在C++中,十六进制数以0x或0X打头,11.6.1节、11.7.4节、11.7.5节和11.7.7节要详细介绍控制数值基数的方法。
1 // Fig. 11.8: fig11_08.cpp
2 // Printing the address stored in a char* variable
3 #include <iostream.h>
4
5 int main()
6{
7 char *string = "test";
8
9 cout << "Value of string is: "<< string
10 << "\nValue of static cast< void *>( string ) is:"
11 << static_cast< void*>( string )<<endl;
12 return 0;
13}
输出结果:
Value of string is:test
Value of staticcast <void*>( string )is:Ox00416D50
图 11.8 输出 char*
类型变量的地址
11.3.4 用成员函数put输出字符和put函数的连续调用 put 成员函数用于输出一个字符,例如语句:
cout.put('A');
将字符A显示在屏幕上。
也可以像下面那样在一条语句中连续调用 put 函数:
cout.put('A').put('\n');
该语句在输出字符A后输出一个换行符。和<<一样,上述语句中圆点运算符(.)从左向右结合,put 成员函数返回调用put的对象的引用。还可以用ASCII码值表达式调用put函数,语句 cout.put(65)
也输出字符A。