C++ primer plus 第17 章 输入、输出和文件:用cout进行格式化
C++ primer plus 第17 章 输入、输出和文件:用cout进行格式化
文章目录
17.2.4 用cout进行格式化
ostream 插入运算符将值转换为文本格式。在默认情况下,格式化值的方式如下。
- 对于char 值,如果它代表的是可打印字符,则将被作为一个字符显示在宽度为一个字符的字段中。
- 对于数值整型,将以十进制方式显示在一个刚好容纳该数字及负号(如果有的话)的字段中。
- 字符串被显示在宽度等于该字符串长度的字段中。浮点数的默认行为有变化。下面详细说明了老式实现和新实现之间的区别。
- 新式:浮点类型被显示为6位,末尾的0不显示(注意,显示的数字位数与数字被存储时精度没有任何关系)。数字以定点表示法显示还是以科学计数法表示(参见第3章),取决于它的值。具体来说,当指数大于等于6或小于等于-5时,将使用科学计数法表示。另外,字段宽度恰好容纳数字和负号(如果有的话)。默认的行为对应于带%g说明符的标准C库函数fprintt()。
- 老式:浮点类型显示为带6位小数,末尾的0不显示(注意,显示的数字位数与数字被存储时的精度没有任何关系)。数字以定点表示法显示还是以科学计数法表示(参见第3章),取决于它的值。另外,字段宽度恰好容纳数字和负号(如果有的话)。
因为每个值的显示宽度都等于它的长度,因此必须显式地在值之间提供空格:否则,相邻的值将不会被分开
程序清单 17.2演示默认的输出情况,它在每个值后面都显示一个冒号(😃,以便可以知道每种情况下的字段宽度。该程序使用表达式1.0/9.0来生成一个无穷小数,以便能够知道打印了多少位。
·注意:并非所有的编译器都能生成符合当前C++标准格式的输出。另外,当前标准允许区域性变化。例如,欧洲实现可能遵循欧洲人的风格:使用逗号而不是句点来表示小数点。也就是说,2.54将被写成2,54。区域库(头文件locale)提供了用特定的风格影响(imbuing)输入或输出流的机制,所以同一个编译器能够提供多个区域选项。本章使用美国格式·。
程序清单 17.2 defaults.cpp
// defaults.cpp -- cout default formats
#include <iostream>
int main()
{
using std::cout;
cout << "12345678901234567890\n";
char ch = 'K';
int t = 273;
cout << ch << ":\n";
cout << t << ":\n";
cout << -t <<":\n";
double f1 = 1.200;
cout << f1 << ":\n";
cout << (f1 + 1.0 / 9.0) << ":\n";
double f2 = 1.67E2;
cout << f2 << ":\n";
f2 += 1.0 / 9.0;
cout << f2 << ":\n";
cout << (f2 * 1.0e4) << ":\n";
double f3 = 2.3e-4;
cout << f3 << ":\n";
cout << f3 / 10 << ":\n";
// std::cin.get();
return 0;
}
每个值都填充自己的字段。注意,1.200末尾的0没有显示出来,但末尾不带0的浮点值后面将有6个空格。另外,该实现将指数显示为3位,而其他实现可能为两位。
1.修改显示时使用的计数系统
ostrcam 类是从ios 类派生而来的,而后者是从ios base 类派生而来的。ios base 类存储了描述格式状态的信息。例如,一个类成员中某些位决定了使用的计数系统,而另一个成员则决定了字段宽度。通过使用控制符(manipulator),可以控制显示整数时使用的计数系统。通过使用iosbase的成员函数,可以控制字段宽度和小数位数。由于ios base类是 ostream的间接基类,因此可以将其方法用于ostream 对象(或子代),如 cout。
·注意:ios base 类中的成员和方法以前位于ios类中。现在,ios basc是ios 的基类。在新系统中,ios是包含 char 和 wchart具体化的模板,而ios base 包含了非模板特性。·
来看如何设置显示整数时使用的计数系统。要控制整数以十进制、十六进制还是八进制显示,可以使用dec、hex和oct控制符。例如,下面的函数调用将cout对象的计数系统格式状态设置为十六进制:
hex(cout);
完成上述设置后,程序将以十六进制形式打印整数值,直到将格式状态设置为其他选项为止。注意,控制符不是成员函数,因此不必通过对象来调用。
虽然控制符实际上是函数,但它们通常的使用方式为:
cout << hex;
ostream 类重载了<<运算符,这使得上述用法与函数调用hex(cout)等价。控制符位于名称空间 std中。程序清单17.3演示了这些控制符的用法,它以3种不同的计数系统显示了一个整数的值极其平方。注可以单独使用控制符,也可将其作为一系列插入的组成部分。意,
程序清单17.3 manip.Cpp
// manip.cpp -- using format manipulators
#include <iostream>
int main()
{
using namespace std;
cout << "Enter an integer: ";
int n;
cin >> n;
cout << "n n*n\n";
cout << n << " " << n * n << " (decimal)\n";
// set to hex mode
cout << hex;
cout << n << " ";
cout << n * n << " (hexadecimal)\n";
// set to octal mode
cout << oct << n << " " << n * n << " (octal)\n";
// alternative way to call a manipulator
dec(cout);
cout << n << " " << n * n << " (decimal)\n";
// cin.get();
// cin.get();
return 0;
}
2.调整字段宽度
您可能已经注意到,在程序清单17.3的输出中各列并没有对齐,这是因为数字的字段宽度不相同。可以使用width成员函数将长度不同的数字放到宽度相同的字段中,该方法的原型为:
int widch();
int width(int i);
第一种格式返回字段宽度的当前设置;第二种格式将字段宽度设置为i个空格,并返回以前的字段宽度值。这使得能够保存以前的值,以便以后恢复宽度值时使用。
width()方法只影响将显示的下一个项目,然后字段宽度将恢复为默认值。例如,请看下面的语句:
Cout << '#';
cout.width(12);
cout << 12 <<“#”<≤ 24 << “#\n"