参考:http://www.weixueyuan.net/view/6409.html
总结:
我们需要借助格式标识符来控制cout对象的输出格式。
在ios_base类中,系统已经定义了很多格式标识符,通过这些标识符,我们可以很好地进行格式化控制,具体见下表。ios_base类中还定义有width和precision等函数。
除了能够直接调用这些格式标识符之外,我们可以借助类中提供的成员函数。
这些函数都是ios_base类的成员函数,可以通过对象直接调用,而cout是basic_ostream的一个对象,basic_ostream继承自ios_base,因此cout可以调用这些函数。
ios_base::showbase,即显示基数,基数的意思就是说在十六进制前加上0x,在八进制前加上0,十进制则不作处理。
一旦格式设置完成,则会一直保持格式,除非取消格式,因此在设置新格式前最好将原有设置的格式都取消。
这些格式化控制除了可以使用格式标识来控制外,我们还可以使用操纵器来控制。
操作器其本质是函数,它可以直接改变流的格式。
C++标准库中预定义了一些操纵器,使用其中带参数的操纵器则需要包含头文件iomanip,下标中列出了一些带参数的操纵器。
----------------------------------
在我们设计程序时,我们通常需要将输出数据以某种格式显示出来,例如我们希望将时间显示为“dd:dd:dd”的形式,如此一来我们就需要借助格式标识符来控制cout对象的输出格式。在ios_base类中,系统已经定义了很多格式标识符,通过这些标识符,我们可以很好地进行格式化控制,具体见下表。除此之外,ios_base类中还定义有width和precision等函数,这些函数同样可以辅助我们进行格式化控制。
格式标识符 | 用途 |
---|---|
boolalpha | 以true和false的形式读写bool类型变量 |
dec | 以十进制的方式进行读写 |
oct | 以八进制的方式进行读写 |
hex | 以十六进制的方式进行读写 |
internal | 放在正负号或基数标识之后 |
left | 左对齐 |
right | 右对齐 |
fixed | 以定点方式表示浮点数 |
scientific | 用科学计数法表示浮点数 |
showbase | 输出时显示基数 |
showpoint | 必须显示小数点 |
showpos | 对非负数显示+号 |
skipws | 忽略空格 |
unitbuf | 写操作完成后清扫所有的缓冲区 |
uppercase | 用大写字母表示十六进制 |
adjustfield | 格式标识必须是left、right或internal |
basefield | 格式标识必须是dec、oct或hex |
floatfield | 格式标识必须是scientific或fixed |
有了表中所列标识符我们确实可以进行格式控制,但是除了能够直接调用这些格式标识符之外,我们可以借助类中提供的成员函数,具体成员函数见下表。
成员函数 | 用途 |
---|---|
flags() | 返回当前的格式标识 |
flags( val ) | 将格式标识设置为val,并返回旧值 |
setf ( val ) | 将val设置为当前的格式标识,并返回旧的格式标识 |
setf ( val, ios_base::basefield ) | 将val设置为当前的格式标识,并返回旧的格式标识,且要求val为iso_base::dec、ios_base::hex或ios_base::oct三者之一 |
setf ( val, ios_base::adjustfield ) | 将val设置为当前的格式标识,并返回旧的格式标识,且要求val为iso_base::left、ios_base::internal或ios_base::right三者之一 |
setf ( ios_base::internal, ios_base::adjustfield ) | 在符号与数据之间填充字符,并返回旧标识 |
setf ( ios_base::scientific, ios_base::floatfield ) |
设置科学计数法并返回旧标识 |
setf ( ios_base::fixed, ios_base::floatfield ) |
设置定点计数法并返回旧标识 |
setf ( 0, ios_base::floatfield ) | 设置默认浮点数表示法并返回旧标识 |
unsetf ( val ) | 清楚指定的标识并返回旧标识 |
这些函数都是ios_base类的成员函数,可以通过对象直接调用,而cout是basic_ostream的一个对象,basic_ostream继承自ios_base,因此cout可以调用这些函数。
例1:
#include<iostream> using namespace std; int main() { ios_base::fmtflags old_val = cout.flags( ios_base::left | ios_base::hex |ios_base::uppercase | ios_base::showbase ); for( int i = 100; i < 150; i ++ ) cout << i << endl; cout<<endl<<endl; cout.unsetf ( ios_base::left | ios_base::hex |ios_base::uppercase ); cout.setf ( old_val ); for( int i = 100; i < 150; i ++ ) cout << i << endl; cout<<endl<<endl; cout.unsetf( old_val ); cout.setf ( ios_base::hex | ios_base::uppercase ); cout << " hex " << 170 << endl; cout.unsetf( ios_base::hex | ios_base::uppercase ); cout.setf ( ios_base::oct ); cout << " oct " << 170 << endl; cout.unsetf( ios_base::oct ); cout.setf ( ios_base::dec ); cout << " dec " << 170 << endl; return 0; }
本例中我们先调用flags函数设置输出格式,格式设置为左对齐和大写的十六进制,之后我们将100~149的数字全部输出,输出完之后我们将刚才设置的格式全部取消,然后重新设置为原始的格式old_val,再将数字100~149的数字重新输出一遍。之后我们演示的是将170按照十六进制、八进制和十进制的形式输出。
在整个程序中由于我们一开始设置了ios_base::showbase,即显示基数,基数的意思就是说在十六进制前加上0x,在八进制前加上0,十进制则不作处理。我们一开始设置了ios_base::showbase后,一直没有取消设置,因此在整个程序输出过程中一直都是加上了基数。出现这种情况也是我们要注意的,一旦格式设置完成,则会一直保持格式,除非取消格式,因此在设置新格式前最好将原有设置的格式都取消。
例2:
#include<iostream> using namespace std; int main() { cout.width ( 6 ); cout << -100 << endl; cout.setf( ios_base::left ,ios_base::adjustfield); cout.width ( 6 ); cout << -100 << endl; cout.unsetf( ios_base::left ); cout.setf( ios_base::right ,ios_base::adjustfield); cout.width ( 6 ); cout << -100 << endl; cout.unsetf( ios_base::right ); return 0; }
在本例中我们调用成员函数width控制输出的宽度为6个字符的位置,之后我们分别设置左对齐和右对齐,然后输出-100。从上面程序中我们可以看出默认是采用右对齐的方式输出的。
当然,这些格式化控制除了可以使用格式标识来控制外,我们还可以使用操纵器来控制,下面我们来简单了解一下操纵器。操作器其本质是函数,它可以直接改变流的格式。
例3:
cout << hex << uppercase << " hex " << 170 << endl; cout << oct << " oct " << 170 << endl; cout << dec << " dec " << 170 << endl;
本例中hex、oct、dec和uppercase都是操纵器,它可以与输入或输出操作符一起使用。
C++标准库中预定义了一些操纵器,使用其中带参数的操纵器则需要包含头文件iomanip,下标中列出了一些带参数的操纵器。
格式标识符 | 作用对象 | 功能 |
---|---|---|
setbase( int n ) | basic_ostream | 将n设置为基数(默认值为0) |
setfill( char_type c ) | basic_ostream | 设置填充字符为c |
setprecision( int n ) | basic_ostream | 设置精度为n |
setw( int n ) | basic_ostream | 设置域宽为n |
setiosflags( val ) | ios_base | 设置指定的标识 |
resetiosflags( val ) | ios_base | 清除指定的标识 |
表中列出的最后两个函数,其参数值为标识,即为格式标识符的组合。