c++格式化输入输出(转)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

c++格式化输⼊输出(转)
C++共有15个输⼊输出格式标记位,这15个标记位均为bit位,每个标记位都有⾃⼰的含义,且可以单独设置。

格式标记位的取值为0或1:0表⽰关闭(不使⽤此格式),1表⽰开启(使⽤此格式)。

15个标记位的含义可参考下⾯三张表:
标记位
含义
boolalpha 如开启,则输⼊和输出使⽤bool值(即Ture或False)
showbase 如开启,则对于输出,使⽤C++ 基数前缀(0,0x)
showpoint 如开启,则显⽰末尾的⼩数点
uppercase 如开启,则对于16进制,使⽤⼤写字母;对于10进制,使⽤E表⽰法
showpos 如开启,则在正数前⾯加上+
标记位
含义
dec 如开启,则使⽤基数10(进⾏输出)
oct 如开启,则使⽤基数8
hex 如开启,则使⽤基数16
fixed 如开启,则使⽤定点计数法
scientific 如开启,则使⽤科学计数法
left 如开启,则使⽤左对齐
right 如开启,则使⽤右对齐
internal 如开启,则符号或基数前缀左对齐,值右对齐
标记位
含义
skipws 如开启,则跳过输⼊流中的空⽩字符
unitbuf 如开启,则每次输出操作后都会清空缓冲区
先来看⼀个简单的程序:
#include <iostream>
using namespace std;
int main()
{
int x;
x = cout.setf(ios::showpos);
cout << x << endl;
x = cout.setf(ios::uppercase);
cout << x << endl;
system("pause");
return 0;
}
输出结果是:
setf()函数⽤于设置格式标记,函数接受⼀个设格式常量作为参数,在设置成功之后函数会返回⼀个值,该值指出了所有15个标记的上⼀次设置情况。

但将这个返回值进⾏输出,并不是每⼀个标记位的bit值,⽽是⼀个整数,为什么?
实际上,这15个bit值视为⼀个整体,从⽽组成⼀个⼆进制数,并能够转化为⼗进制数。

这15个标记位的排列顺序是:
uppercase unitbuf skipws showpos showpoint showbase scientific right oct left internal hex fixed dec boolalpha
⽐如,setf()函数第⼀次的返回值是4098,这个值实际上是输出格式的初始状态,转化⼆进制为001000000000010,那么格式状态为:
uppercase unitbuf skipws showpos showpoint showbase scientific right oct left internal hex fixed dec boolalpha 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0
⽽6146转化为⼆进制001100000000010,这⼀次的值反映的是开启了showpos位后的格式状态:
uppercase unitbuf skipws showpos showpoint showbase scientific right oct left internal hex fixed dec boolalpha 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0
两次对⽐,我们可以看出,的确是在初始状态的基础上开启了showpos位。

接着我们来看看格式常量,格式常量⼀共有18个,其中15个⽤于打开相应的格式标记为,另外3个做为指⽰功能⽤#include <iostream>
using namespace std;
int main()
{
cout << "boolalpha " << ios::boolalpha <<endl;
cout << "dec " << ios::dec << endl;
cout << "fixed " << ios::fixed << endl;
cout << "hex " <<ios::hex << endl;
cout << "internal " << ios::internal << endl;
cout << "left " << ios::left << endl;
cout << "oct " << ios::oct << endl;
cout << "right " << ios::right << endl;
cout << "scientific " << ios::scientific << endl;
cout << "showbase " << ios::showbase <<endl;
cout << "showpoint " << ios::showpoint <<endl;
cout << "showpos " << ios::showpos <<endl;
cout << "skipws " << ios::skipws << endl;
cout << "unitbuf " << ios::unitbuf << endl;
cout << "uppercase " << ios::uppercase <<endl;
cout << endl;
cout << "basefield " << ios::basefield << endl;
cout << "adjustfield " << ios::adjustfield << endl;
cout << "floatfield " << ios::floatfield << endl;
system("pause");
return 0;
}
格式常量
⼗进制值
意义
ios::boolalpha 1
开启boolalpha标记位,输⼊和输出使⽤bool值(即Ture或False)
ios::showbase 512
开启showbase标记位,对于输出,使⽤C++ 基数前缀(0,0x)
ios::showpoint 1024
开启showpoint标记位,显⽰末尾的⼩数点
ios::uppercase 16384
开启uppercase标记位,对于16进制,使⽤⼤写字母;对于10进制,使⽤E表⽰法
ios::showpos 2048
开启showpos标记位,在正数前⾯加上+
格式常量
⼗进制值
意义
格式常量
⼗进制值
意义
ios::basefield 74
指⽰相关标记位:dec、oct、hex ios::dec 2
开启dec标记位,使⽤基数10
ios::oct 64
开启oct标记位,使⽤基数8
ios::hex 8
开启hex标记位,使⽤基数16
ios::floatfield 260
指⽰相关标记位:fixed、scientific ios::fixed 4
开启fixed标记位,使⽤定点计数法
ios::scientific 256
开启scientific标记位,使⽤科学计数法
ios::adjustfield 176
指⽰相关标记位:left、right、internal ios::left 32
开启left标记位,使⽤左对齐
ios::right 128
开启right标记位,使⽤右对齐
ios::internal 16
开启internal标记位,符号或基数前缀左对齐,值右对齐
注意:这些都是常量,是作为函数参数来设置格式状态,⽽不是格式标记位的存储空间。

15个蓝⾊的格式常量⽤来打开对应的格式标记位,如果将其⼗进制值转化为⼆进制,再于标记位顺序表⽐对,就可以看出来。

3个绿⾊的格式常量⽤来指⽰标记位,为什么要指⽰?⽐如:dec、oct、hex是不可能同时打开的,⽽ios::basefield则指⽰这三个标记位为⼀组,74=2+64+8,这意味着它转化为⼆进制的⽐对情况是dec、oct、hex为1,但它不是设置标记位,⽽是指⽰,具体原理在setf()函数中详细解释。

最后来看看setf()函数:
setf()函数有两种原型,⼀种是fmtflags setf ( fmtflags );
它接收⼀个参数,该参数是⼀种标记类型,提供实参时,可以是整数,该整数转化为⼆进制后赋给格式状态。

但这种⽅法抽象且不安全。

也可以将格式常量作为实参提供给函数,在这种情况下,setf()函数会打开相应的标记位,且不会影响其它标记位。

但这种⽅法仍不安全。

很明显,既打开dec标记位,⼜打开oct标记位是没有意义的。

--------------------------------------------------------------------------------
另⼀种原型是fmtflags setf ( fmtflags , fmtflags );
它接收两个标记类型的参数。

第⼀个参数指出要打开的标记位,第⼆个参数则是指⽰要清除的⼀批相关位。

⽐如:cout.setf( ios::hex, ios::basefield ); 这表⽰使⽤16进制输出格式。

⾸先,ios::basefield指⽰出了要清除的标记位,setf()函数将ios::basefield所指⽰的标记位,即dec、oct、hex全部清零。

然后ios::hex使得setf()函数打开hex标记位。

这是⼀种安全的⽅法,避免了同时打开dec、hex两个标记位等没有实际意义的情况发⽣。

setf()是如何实现清除的?
ios::basefield转化为⼆进制000000001001010,这三个1的位置指⽰的是dec、oct、hex标记位。

setf()函数将这个⼆进制数取反111111*********,然后与原格式状态标记位进⾏“与”操作,使得原格式状态的dec、oct、hex标记位为0,⽽其它标记位不变。

(参看
《C++ primer plus》683页位操作)
然后setf()函数根据第⼀个参数ios::hex将格式状态的hex标记位打开,其它标记位不变。

⾄此,格式设置就成功完成了。

我们也可以看
出,setf()函数不会影响⽆关标记位的状态。

相关文档
最新文档