11.7 流格式状态
各种格式标志指定了在 I/O 流中执行的格式类型。成员函数 serf、unserf 和 flag 控制标志的设置。
11.7.1 格式状态标志
图 11.20 中的格式状态标志在类ios中被定义为枚举值,留到下几节解释。
虽然成员函数 flags、serf 和 unseff 可以控制这些标志,但是许多C++程序员更喜欢使用流操纵算子(见11.7.8节)。程序员可以用按位或操作(|)把各种标志选项结合在一个long类型的值中(见图11.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 | 指事实上浮点数输出采用定点符号,保证小数点后面有一定位数 |
图 11.20 格式状态标志
11.7.2 尾数零和十进制小数点(ios::showpoint)
设置 showpoint 标志是为了强制输出浮点数的小数点和尾数零。若没有设置 showpoint,浮点数 79.0 将被打印为 79,否则打印为 79.000000(或由当前精度指定的尾数零的个数)。图11.21中的程序用成员函数 setf 设置 showpoint 标志,从而控制了浮点数的尾数零和小数点的输出。
i // Fig. 11.21: fig11_21.cpp
2 // Controlling the printing of trailing zeros and decimal
3 // points for floating-point values.
4 #include <iostream.h>
5 #include <iomanip.h>
6 #include <math.h>
7
8 int main()
9 {
10 cout << "Before setting the ios::showpoint flag\n"
11 << "9.9900 prints as: "<< 9.9900
12 << "\n9.9000 prints as: "<< 9.9000
13 << "\n9.0000 prints as: "<< 9.0000
14 << "\n\nAfter setting the ios::showpoint flag\n";
15 cout.setf( ios::showpoint );
16 cout << "9.9900 prints as: "<< 9.9900
17 << "\n9.90O0 prints as: "<< 9.9000
18 << "\n9.0000 prints as: "<< 9.0000 << endl;
19 return 0;
20 }
输出结果:
Before setting the ios::showpolnt flag
9.9900 prints as: 9.99
9.9000 prints as: 9.9
9.9000 prints as: 9
After setting the ios::showpoint flag
9.9900 prints as: 9.99000
9.9000 prints as: 9.90000
9.0000 prints as: 9.00000
图 11.21 控制浮点数的尾数零和小数点的输出
11.7.3 对齐(ios::left、ios::right、ios::internal)
left 标志可以使输出域左对齐并把填充字符放在输出数据的右边,right 标志可以使输出域右对齐并把填充字符放在输出数据的左边。填充的字符由成员函数fill或参数化的流操纵算子setfill指定(见7.4节)。图11.22用流操纵算子 setw、setiosflags、reseticsfiags 以及成员函数serf和unsetf控制整数值在域宽内左对齐和右对齐。
1 // Fig. 11.22: fig11_22.cpp
2 // Left-justification and right-justification.
3 #include <iostream.h>
4 #include <iomanip.h>
6 int main()
7{
8 int x = 12345;
9
10 cout << "Default is right justified:\n"
11 << setw(10) << x << "\n\nUSING MEMBER FUNCTIONS"
12 << "\nUse serf to set ios::left:\n" << setw(10);
13
14 cout.setf( ios::left, ios::adjustfield );
15 cout << x << "\nUse unsetf to restore default:\n";
16 cout.unsetf( ios::left );
17 cout << setw( 10 ) << x
18 << "\n\nUSING PARAMETERIZED STREAM MANIPUAATORS"
19 << "\nUse setiosflags to set ios::left:\n"
20 << setw( 10 ) << setiosflags( ios::left ) << x
21 << "\nUse resetiosflags to restore default:\n"
22 << setw( 10 ) << resetiosflags( ios::left )
23 << x << endl;
24 return 0;
25 }
输出结果:
Default is right justified:
12345
USING MEMBER FUNCTIONS
Use setf to set ios::left:
12345
Use unsetf to restore default:
12345
USING PARAMETERIZED STREAM MANIPULATORS
Use setiosflags to set ios::left:
12345
Use resetiosflags to restore default:
12345
图 11.22 左对齐和右对齐
internal 标志指示将一个数的符号位(设置了 ios::showbase 标志时为基数,见11.7.5节)在域宽内左对齐,数值右对齐,中间的空白由填充字符填充。left、right 和 internal 标志包含在静态数据成员 ios::adjustfield 中。在设置 left、right 和 internal 对齐标志时,setf 的第二个参数必须是ios::adjustfield,这样才能使 serf 只设置其中一个标志(这三个标志是互斥的)。图 11.23 中的程序用流操纵算子 setiosflags 和 setw 指定中间的空白。注意,ios::showpos 标志强制打印了加号。
1 // Fig. 11.23: figll_23.cpp
2 // Printing an integer with internal spacing and
3 // forcing the plus sign.
4 #include <iostream.h>
5 #include <iomanip.h>
6
7 int main()
8 {
9 cout << setiosflags( ios::internal | ios::showpos )
10 << setw( 10 ) << 123 << endl;
11 return O;
12 }
输出结果:
+ 123
图 11.23 打印中间带空白的整数并强制输出加号
11.7.4 设置填充字符(fill、setfill)
成员函数fill设置用于使输出域对齐的填充字符,如果不特别指定,空格即为填充字符。fill函数返回以前设置的填充字符。图11.24中的程序演示了使用成员函数fill和流操纵算子,setfill来控制填充字符的设置和清除。
1 // Fig. 11.24: fig11_24.cpp
2 // Using the fill member function and the setfill
3 // manipulator to change the padding character for
4 // fields larger than the values being printed.
5 #include <iostream.h>
6 finclude <iomanip.h>
7
8 int main()
9 {
10 int x = 10000;
11
12 cout << x << "printed as iht right and left justified\n"
13 << "and as hex with internal justification.\n"
14 << "Using the default pad character (space):\n";
15 cout.setf( ios::showbase );
16 cout << setw( 10 ) << x << '\n';
17 cout.setf( ios::left, ios::adjustfield );
18 cout << setw( 10 } << x << '\n';
19 cout.serf( ios::internal, ios::adjustfield );
20 cout << setw( 10 ) << hex << x;
21
22 cout << "\n\nUsing various padding characters:\n";
23 cout.setf( ios::right, ios::adjustfield );
24 cout.fill( '*' );
25 cout << setw( 10 ) << dec << x << '\n';
26 cout.setf( ios::left, ios::adjustfield );
27 cout << setw( 10 ) << setfill( '%' ) << x << '\n';
28 cout.setf( ios::internal, ios::adjustfield );
29 cout << setw( 10 ) << setfill( '^' ) << hex << x << endl;
30 return 0;
31 }
输出结果:
10000 printed as int right and left justified
and as hex with internal justification.
Using the default pad character (space):
l0000
10000
0x2710
Using various padding characters:
*****10000
10000%%%%%
图 11.24 用 fill 和 setfill 为实际宽度小于域宽的数据改变填充字符
11.7.5 整数流的基数(ios::dec、ios::oct、ios::hex、ios::showbase)
静态成员 ios::basefield(在 setf 中的用法与 ios::adjustfield 类似)包括 ios::oct、ios::hex 和 ios::dec 标志位,这些标志位分别指定把整数作为八进制、十六进制和十进制值处理。如果没有设置这些位,则流插入运算默认整数为十进制数,流读取运算按整数提供的方式处理数据(即以零打头的整数按八进制数处理,以0x或0X打头的按十六进制数处理,其他所有整数都按十进制数处理)。一旦为流指定了特定的基数,流中的所有整数都按该基数处理,直到指定了新的基数或程序结束为止。
设置showbase标志可强制输出整数值的基数。十进制数以通常方式输出,输出的八进制数以0打头,输出的十六进制数以0x或OX打头(由uppercase标志决定是0x还是0X,见11.7.7节)。图11.25中的程序用showbase标志强制整数按十进制、八进制和十六进制格式打印。
1 // Fig. 11.25: figll_25.cpp
2 // Using the ios::showbase flag
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 int main()
7 {
8 int x = 100;
9
10 cout << setiosflags( ios::showbase )
11 << "Printing integers preceded by their base:\n"
12 << x << '\n'
13 << oct << x << '\n'
14 << hex << x << endl;
15 return 0;
16 }
输入结果:
Printing integers preceded by their base:
I00
0144
0x64
图 11.25 使用 ios::showbase 标志
11.7.6 浮点数和科学记数法(ios::scientific、ios::fixed)
ios::scientific 和 ios::fixed 标志包含在静态数据成员ios::floatfield中(在setf中的用法与ios:: adjustfield和ios::basefield类似)。这些标志用于控制浮点数的输出格式。设置scientific标志使浮点数按科学记数法输出,设置fixed标志使浮点数按照定点格式输出,即显示出小数点,小数点后边有指定的位数(由成员函数precision指定)。若没有这些设置,则浮点数的值决定输出格式。
调用 cout.setf(O,ios::floatfield) 恢复输出浮点数的系统默认格式。图 11.26 中的程序示范了以定点格式和科学记数法显示的浮点数。
1 // Fig. 11.26: flg11_26.cpp
2 // Displaying floating-point values in system default,
3 // scientific, and fixed formats.
4 #include <iostream.h>
5
6 int main()
7 {
8 double x = .001239567, y = 1.946e9;
9
10 cout << "Displayed in default format:\n"
11 << x << '\t' << y << '\n';
12 cout.setf( ios::scientific, ios::floatfield );
13 cout << "Displayed in scientific format:\n"
14 << x << '\t' << y << '\n';
15 cout.unsetf( ios::scientific );
16 cout << "Displayed in default format after unsetf:\n"
17 << x << ,\t' << y << ,\n,;
18 cout.setf( ios::fixed, ios::floatfield );
19 cout << "Displayed in fixed format:\n"
20 << x << '\t' << y << endl;
21 return 0;
22 }
输出结果:
Displayed in default format:
0.00123457 1.946e+009
Displayed in scientific format:
1.234567e-003 1.946000e+009
Displayed in default format after unsetf:
0.00123457 1.946e+009
Displayed in fixed format:
0.001235 1946000000.000000
图 11.26 以系统默认格式、科学计数法和定点格式显示浮点数
11.7.7 大/小写控制(ios::upercase)
设置 ios::uppercase 标志用来使大写的X和E分别同十六进制整数和以科学记数法表示的浮点数一起输出(见图11.27)一旦设置ios::uppercase标志,十六进制数中的所有字母都转换成大写。
1 // Fig. 11.27: fig11_27.cpp
2 // Using the ios::uppercase flag
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 int main()
7 {
8 cout << setiosflags( ios::uppercase )
9 << "Printing uppercase letters in scientific\n"
10 << "notation exponents and hexadecimal values:\n"
11 << 4.345e10 << '\n' << hex << 123456789 << endl;
12 return O;
13 }
输出结果:
Printing uppercase letters in scientific
notation exponents and hexadecimal values:
4.395E+010
75BCD16
图 11.27 使用 ios::uppercase 标志
11.7.8 设置及清除格式标志(flags、setiosflags、resetosflags)
无参数的成员函数flags只返回格式标志的当前设置(long类型的值)。带一个long类型参数的成员函数flags按参数指定的格式设置标志,返回以前的标志设置。flags的参数中未指定的任何格式都会被清除。图11.18的程序用成员函数flags设置新的格式状态和保存以前的格式状态,然后恢复原来的格式设置。
1 // Fig. 11.28: fig11_28.cpp
2 // Demonstrating the flags member function.
3 #include <iostream.h>
4
5 int main()
6 {
7 int i = 1000;
8 double d = 0.0947625;
9
10 cout << "The value of the flags variable is:"
11 << cout.flags()
12 << "\nPrint int and double in original format:\n"
13 << i << '\t' << d << "\n\n";
14 long originalFormat =
15 cout.flags( ios::oct | ios::scientific );
16 cout << "The value of the flags variable is:"
17 << cout.flags()
18 << "\nPrint int and double in a new format\n"
19 << "specified using the flags member function:\n"
20 << i << '\t' << d << "\n\n";
21 cout.flags( originalFormat );
22 cout << "The value of the flags variable is:"
23 << cout.flags()
24 << "\nPrint values in original format again:\n"
25 << i << '\t' << d << endl;
26 return 0;
27 }
输出结果:
The value of the flags variable is: 0
Print int and double in original format:
1000 0.0947628
The value of the flags variable is: 4040
Print iht and double in a new format
Specified using the flags member function:
1750 9.476280e-002
The value of the flags variable is: 0
Print values in original format again:
1000 0.0947628
图 11.28 演示成员函数 flags
成员函数 serf 设置参数所指定的格式标志,并返回 long 类型的标志设置值,例如:
long previousFlagSettings = cout.setf(ios::showpoint | ios::showpos);
带两个 long 型参数的setf成员函数.例如:
cout.setf(ios::left,ios::adjustfield);
首先清除 ios::adjustfield 位,然后设置 ios::left 标志。该版本的 setf 用于与 ios::basefield(用 ios::dec、ios::oct 和 ios::hex 表示)、ios::floatfield(用 ios::scientific 和 ios::fixed 表示)和ios::adjustfiald(用 ios::left、ios::right 和 ios::internal 表示)相关的位段。
成员函数unsetf清除指定的标志并返回清除前的标志值。