20 in hexadecimal is: 14 20 in octal is: 24 20 in decimal is: 20
图 3.16 使用流操纵算子hex、oct、dec和setbase
3.6.2 设置浮点数精度(precision、setprecision)
在C++中可以人为控制浮点数的精度,也就是说可以用流操纵算子setprecision或成员函数percision控制小数点后面的位数。设置了精度以后,该精度对之后所有的输出操作都有效,直到下一次设置精度为止。无参数的成员函数percision返回当前设置的精度。图3.17中的程序用成员函数precision和流操纵算子setprecision打印出了2的平方根表,输出结果的精度从0连续变化到9。
1 // Fig. 3.17: fig11_17.cpp
2 // Controlling precision of floating-point values 3 #include
9 double root2 = sqrt( 2.0 ); 10 int places; 11
12 cout << setiosflags(ios::fixed)
13 << \14 << \
15 << \16
17 for ( places = 0; places <= 9; places++ ) { 18 cout.precision( places ); 19 cout << root2 << '\\n'; 20 } 21
22 cout << \
23 << \24
25 for ( places = 0; places <= 9; places++ )
26 cout << setprecision( places ) << root2 << '\\n'; 27
28 return 0; 29 }
-46-
输出结果:
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
图3.17 控制浮点数的精度
3.6.3 设置域宽(setw、width)
成员函数ios.width设置当前的域宽(即输入输出的字符数)并返回以前设置的域宽。如果显示数据所需的宽度比设置的域宽小,空位用填充字符填充。如果显示数据所需的宽度比设置的域宽大,显示数据并不会被截断,系统会输出所有位。
图3.18中的程序示范了成员函数width的输入和输出操作。注意,输入操作提取字符串的最大宽度比定义的域宽小1,这是因为在输入的字符串后面必须加上一个空字符。当遇到非前导空白字符时,流读取操作就会终止。流操纵算子setw也可以用来设置域宽。注意:提示用户输入时,用户应输入一行文本并按Enter键加上文件结束符(
2 // Demonstrating the width member function 3 #include
-47-
5 int main() 6{
7 int w = 4;
8 char string[ 10 ]; 9
10 cout << \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
图 3.18 演示成员函数width
3.6.4 用户自定义的流操纵算子
用户可以建立自己的流操纵算子。图3.19中的程序说明了如何建立和使用新的流操纵算子bell、ret、tab和endline。用户还可以建立自己的带参数的流操纵算子,这方面内容可参看系统的手册。
1 /! Fig. 3.19: fig11_19.cpp
2 // Creating and testing user-defined, nonparameterized 3 // stream manipulators. 4 #include
-48-
5 using namespace std;
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 << \25 << 'a' << tab << 'b' << tab << 'c' << endLine 26 << \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: --------........
图 3.19 建立并测试用户自定义的、无参数的流操作算子
3.7 流格式状态
各种格式标志指定了在I/O流中执行的格式类型。成员函数serf、unserf和flag控制标志的设置。
-49-
3.7.1 格式状态标志
图3.20中的格式状态标志在类ios中被定义为枚举值,留到下几节解释。
虽然成员函数flags、serf和unseff可以控制这些标志,但是许多C++程序员更喜欢使用流操纵算子(见3.7.8节)。程序员可以用按位或操作(|)把各种标志选项结合在一个long类型的值中(见图3.23)。调用成员函数flags并指定要进行或操作的标志选项就可以在流中设置这些标志,并返回一个包含以前标志选项的long类型的值。返回值通常要保存起来,以便用保存值调用flags来恢复以前的流选项。
flags函数必须指定一个代表所有标志设置的值。而带有一个参数的函数setf可指定一个或多个要进行或操作的标志,并把它们与现存的标志设置相“或”,形成新的格式状态。
参数化的流操纵算子setiosflags与成员函数serf执行同样的功能。流操纵算子resetiosflags与成员函数unsetf执行同样的功能。不论使用哪一种流操纵算子,在程序中都必须包含头文件iomanip.h。
skipws标志指示>>跳过输人流中的空白字符。>>的默认行为是跳过空白字符,调用unsetf(ios::skipws)可改变默认行为。流操纵算子ws也可用于指定跳过流中的空白字符。 ---------------------------------------------------------------------------------------------- 格式状态 说明
---------------------------------------------------------------------------------------------- ios::skipws 跳过输入流中的空白字符
ios::left 在域中左对齐输出,必要时在右边显示填充字符 ios:right 在域中右对齐输出,必要时在左边显示填充字符
ios::internal 表示数字的符号应在域中左对齐,而数字值应在域中右对齐(即在符号和数字之间填充字符
ios::dec 指定整数应作为十进制(基数10)值 ios::oct 指定整数应作为八进制(基数8)值 ios::hex 指定整数应作为十六进制(基数16)值
ios::showbase 指定在数字疥面输出进制(0表示八进制,0x或0X表示十六进制)
ios::showpoint 指定浮点数输出时应带小数点。这通常和ios::fixed一起使用保证小数点后面有一定位数
ios::uppercase 指定表示十六进制Rx应为大写,表示浮点科学计数法的e应为大写 ios::showpos 指定正数和负数前面分别加上正号或-号 ios::scientific 指事实上浮点数输出采用科学计数法
ios::fixed 指事实上浮点数输出采用定点符号,保证小数点后面有一定位数
-----------------------------------------------------------------------------------------------
图 3.20 格式状态标志
3.7.2 尾数零和十进制小数点(ios::showpoint)
设置showpoint标志是为了强制输出浮点数的小数点和尾数零。若没有设置showpoint,浮点数79.0将被打印为79,否则打印为79.000000(或由当前精度指定的尾数零的个数)。图3.21中
-50-