当前位置: 首页 > 文档资料 > C++大学教程 >

11.6 流操纵算子

优质
小牛编辑
136浏览
2023-12-01

C++ 提供了大量的用于执行格式化输入/输出的流操纵算子。流操纵算子提供了许多功能,如设置域宽、设置精度、设置和清除格式化标志、设置域填充字符、刷新流、在输出流中插入换行符并刷新该流、在输出流中插入空字符、跳过输入流中的空白字符等等。下面几节要介绍这些特征。

11.6.1 整数流的基数:流操纵算子 dec、oct、hex 和 setbase

整数通常被解释为十进制(基数为10)整数。如下方法可改变流中整数的基数:插人流操纵算子hex可设置十六进制基数(基数为16)、插人流操纵算子oct可设置八进制基数(基数为8)、插人流操纵算子 dec 可恢复十进制基数。

也可以用流操纵算子 setbace 来改变基数,流操纵算于 setbase 带有一个整数参数 10、8 或 16。因为流操纵算子 setbase 是带有参数的,所以也称之为参数化的流操纵算子。使用 setbose 或其他任何参数化的操纵算子都必须在程序中包含头文件 iomanip.h。如果不明确地改变流的基数,流的基数是不变的。图 11.16 中的程序示范了流操纵算子hex、oct、dec 和 setbase 的用法。

1 // Fig. 11.16: fig11_16.cpp
2 // Using hex, oct, dec and setbase stream manipulators.
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 int main()
7{
8 int n;
9
10 cout << "Enter a decimal number: ";
11 cin >> n;
12
13 cout << n << "in hexadecimal is:"
14 << hex << n << '\n'
15 << dec << n << "in octal is:"
16 << oct << n << '\n'
17 << setbase( 10 ) << n <<" in decimal is:"
18 << n << endl;
19
20 return 0;
21 }

输出结果:

Enter a decimal number: 20
20 in hexadecimal is: 14
20 in octal is: 24
20 in decimal is: 20

图 11.16 使用流操纵算子 hex、oct、dec 和 setbase

11.6.2 设置浮点数精度(precision、setprecision)

在 C++ 中可以人为控制浮点数的精度,也就是说可以用流操纵算子 setprecision 或成员函数percision控制小数点后面的位数。设置了精度以后,该精度对之后所有的输出操作都有效,直到下一次设置精度为止。无参数的成员函数 percision 返回当前设置的精度。图11.17中的程序用成员函数precision和流操纵算子setprecision打印出了2的平方根表,输出结果的精度从0连续变化到9。

1 // Fig. 11.17: fig11_17.cpp
2 // Controlling precision of floating-point values
3 #include <iostream.h>
4 #include <iomanip.h>
5 #include <math.h>
6
7 int main()
8
9 double root2 = sqrt( 2.0 );
10 int places;
11
12 cout << setiosflags(ios::fixed)
13 << "Square root of 2 with precisions 0-9.\n"
14 << "Precision set by the"
15 << "precision member function:" << endl;
16
17 for ( places = 0; places <= 9; places++ ) {
18 cout.precision( places );
19 cout << root2 << '\n';
20 }
21
22 cout << "\nPrecision set by the"
23 << "setprecision manipulator:\n";
24
25 for ( places = 0; places <= 9; places++ )
26 cout << setprecision( places ) << root2 << '\n';
27
28 return 0;
29 }

输出结果:

Square root of 2 with pzecisions 0-9.
Precision set by the precision member function:
1
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142136
1.41421356
1.414213562
Precision set by the setprecision manipulator:
1
1.4
1.4l
1.414
1.4142
1.41421 ·
1.414214
1.4142136
1.41421356
1.414213562

图11.17 控制浮点数的精度

11.6.3 设置域宽(setw、width)

成员函数 ios.width 设置当前的域宽(即输入输出的字符数)并返回以前设置的域宽。如果显示数据所需的宽度比设置的域宽小,空位用填充字符填充。如果显示数据所需的宽度比设置的域宽大,显示数据并不会被截断,系统会输出所有位。

常见编程错误 11.4
域宽设置仅对下一行流读取或流插入操作有效,在一次操作完成之后,城宽又被置回0,也就是输出值按照所需要的宽度来输出。不带参数的width函数返回当前域宽。认为域宽设置适用于所有输出走十逻辑错误。

常见编程错误 11.5
未对所处理的输出数据提供足够的域宽时,输出数据将按需要的域宽进行输出,有可能产生难以阅读的输出结果。

图 11.18 中的程序示范了成员函数width的输入和输出操作。注意,输入操作提取字符串的最大宽度比定义的域宽小1,这是因为在输入的字符串后面必须加上一个空字符。当遇到非前导空白字符时,流读取操作就会终止。流操纵算子setw也可以用来设置域宽。注意:提示用户输入时,用户应输入一行文本并按Enter键加上文件结束符(<ctrl>-z对于IDMPC兼容系统;<ctrl>-d 对于 UNIX 与 Macintosh 系统)。

1 // fig11_18.cpp
2 // Demonstrating the width member function
3 #include <iostream.h>
4
5 int main()
6{
7 int w = 4;
8 char string[ 10 ];
9
10 cout << "Enter a sentence:\n";
11 cin.width( 5 );
12
13 while (cin >> string ) {
14 cout.width( w++ );
15 cout << string << endl;
16 cin.width( 5 );
17 }
18
19 return 0;
20 }

输出结果:

Enter a sentence:
This is a test of the width member function
This
is
a
test
of
the
widt
h
memb
er
func
tion

图 11.18 演示成员函数 width

11.6.4 用户自定义的流操纵算子

用户可以建立自己的流操纵算子。图 11.19 中的程序说明了如何建立和使用新的流操纵算子 bell、ret、tab 和 endline。用户还可以建立自己的带参数的流操纵算子,这方面内容可参看系统的手册。

1 /! Fig. 11.19: fig11_19.cpp
2 // Creating and testing user-defined, nonparameterized
3 // stream manipulators.
4 #include <iostream.h>
5
6 // bell manipulator (using escape sequence \a)
7 ostream& bell( ostream& output ) { return output << '\a'; }
8
9 // ret manipulator (using escape sequence \r)
10 ostream& ret( ostream& output ) ( return output << '\r'; }
11
12 // tab manipulator (using escape sequence \t)
13 ostream& tab( ostream& output ) { return output << '\t'; ]
14
15 // endLine manipulator (using escape sequence \n
16 // and the flush member function)
17 ostream& endLine( ostream& output )
18 {
19 return output << '\n' << flush;
20 }
21
22 int main()
23 {
24 cout << "Testing the tab manipulator:" << endLine
25 << 'a' << tab << 'b' << tab << 'c' << endLine
26 << "Testing the ret and bell manipulators:"
27 << endLine << ".......... ";
28 cout << bell;
29 cout << ret << ......... << endLine;
30 return 0;
31 }

输出结果:

Testing the tab manipulator:
a b c
Testing the ret and bell manipulators:
--------........

图 11.19 建立并测试用户自定义的、无参数的流操作算子