由于C++的格式控制对我来说完全是个新的东西,我在这里总结下

在上一篇总结里也提到过,ostream是从ios类派生出来的,而ios类是从ios_base类派生出来的。
对于输出的格式控制,ios_base类起到了至关重要的作用,因为他提供了控制格式的成员方法和成员数据。

字段宽度和精度

先介绍这两个,因为控制这两个格式的成员数据是单独存储在ios_base类中的。

控制字段宽度

函数原型:

1
2
int width();  // 返回字段宽度的当前设置
int width(int i); // 将字段宽度设置为i个空格,并返回以前的字符宽度值

width()方法只影响接下来显示的一个项目

ios_base类的setf()成员函数

ios_base类中有一个protected成员数据,这个数据的每一位(这里的位是指bit)分别控制着格式化的各个方面,例如计数系统,是否显示结尾的0等。打开一个位意味着相应的位的值被设为1.例如hex、dec、oct控制符调整计数系统的三个标记位。其中setf()成员方法控制着调整标记位的途径

setf()有两个原型:

1
2
fmtflag setf(fmtflag);
fmtflag setf(fmtflag, fmtflag);

fmtflagbitmask类型的typedef,用于存储格式标记。它可以是整形、枚举、也可以是STL bitset容器。这里的主要思想是:
每一位都是可以单独访问的,都有自己的含义,也就是需要位操作。

setf()函数通过传递给他的参数来改变状态位。但是直接操作位比较麻烦,所以在ios_base中定义了一些常量代表位值,例如ios_base::boolalpha, ios_base::showbase

第二种原型,提供了两个fmtflag值,第一个用于设置某一位打开或关闭,第二位的作用是清扫其他位。其实两个参数的作用顺序是相反的,先用第二个参数清除一些相关位,在用第一个参数设置哪一位。
通过这两个不同的组合可以进行输出格式的设置:

1
2
3
4
5
6
cout.setf(ios_base::floatfield, ios_base::fixed);       // 使用定点计数法
cout.setf(ios_base::floatfield, ios_base::scientific); // 使用科学计数法
/************************************************************************/
cout.setf(ios_base::adjustfield, ios_base::left); // 使用左对齐
cout.setf(ios_base::adjustfield, ios_base::right); // 使用右对齐
cout.setf(ios_base::adjustfield, ios_base::internal); // 符号或基数前缀左对齐,值右对齐

清除设置unsetf()

unsetf()的原型:

1
void unsetf(fmtflag mask);

mask将所有的位都设为1,是的对应的位被复位(通过位运算)。例如:
1
2
cout.setf(ios_base::showpoint);  // 将其中的某位设为1
cout.setf(ios_base::showpoint); // 将相应的那位恢复位0

Comments

2016-03-16