格式化占位符[编辑]
格式化字符串中的占位符用于指明输出的参数值如何格式化。
格式化占位符(format placeholder)
语法是:
%[parameter][flags][field width][.precision][length]type Parameter可以忽略或者是:
Flags可为0个或多个:
Field Width给出显示数值的最小宽度,典型用于制表输出时填充固定宽度的表目。
实际输出字符的个数不足域宽,则根据左对齐或右对齐进行填充。
实际输出字符的个数超过域宽并不引起数值截断,而是显示全部。
宽度值的前导0被解释为0填充标志,如上述;前导的负值被解释为其绝对值,负号解释为左对齐标志。
如果域宽值为*,则由对应的函数参数的值为当前域宽。
Precision通常指明输出的最大长度,依赖于特定的格式化类型。
对于d、i、u、x、o的整型数值,是指最小数字位数,不足的位要在左侧补0,如果超过也不截断,缺省值为1。
对于a,A,e,E,f,F的浮点数值,是指小数点右边显示的数字位数,必要时四舍五入;缺省值为6。
对于g,G的浮点数值,是指有效数字的最大位数。
对于s的字符串类型,是指输出的字节的上限,超出限制的其它字符将被截断。
如果域宽为*,则由对应的函数参数的值为当前域宽。
如果仅给出了小数点,则域宽为0。
Length指出浮点型参数或整型参数的长度。
此项Microsoft称为“Size”。
可以忽略,或者是下述:
此外,在ISO C99广泛接受前,还有几个平台相关的length选项:
ISO C99的头文件inttypes.h包含了许多宏,用于平台独立的printf编码。
例如:
类型[编辑]
Type,也称转换说明(conversion specification/specifier),可以是:
字
符
描述
d,i 有符号十进制数值int。
'%d'与'%i'对于输出是同义;但对于scanf()输入二者不同,其中%i在输入值有前缀0x或0时,分别表示16进制或8进制的值。
如果指定了精度,则输出的数字不足时在左侧补0。
默认精度为1。
精度为0且值为0,则输出为空。
u 十进制unsigned int。
如果指定了精度,则输出的数字不足时在左侧补0。
默认精度为1。
精度为0且值为0,则输出为空。
f,F double型输出10进制定点表示。
'f'与'F'差异是表示无穷与NaN时,'f'输出'inf', 'infinity'与'nan';'F'输出'INF', 'INFINITY'与'NAN'。
小数点后的数字位数等于精度,最后一位数字四舍五入。
精度默认为6。
如果精度为0且没有#标记,则不出现小数点。
小数点左侧至少一位数字。
e,E double值,输出形式为10进制的([-]d.ddd e[+/-]ddd). E版本使用的指数符号为E(而不是e)。
指数部分至少包含2位数字,如果值为0,则指数部分为00。
Windows系统,指数部分至少为3位数字,例如1.5e002,也可用Microsoft版的运行时函数
_set_output_format修改。
小数点前存在1位数字。
小数点后的数字位数等于精度。
精度默认为6。
如果精度为0且没有#标记,则不出现小数点。
g,G double型数值,精度定义为全部有效数字位数。
当指数部分在闭区间 [-4,精度] 内,输出为定点形式;否则输出为指数浮点形式。
'g'使用小写字母,'G'使用大写字母。
小数点右侧的尾数0不被显示;显示小数点仅当输出的小数部分不为0。
x,X 16进制unsigned int。
'x'使用小写字母;'X'使用大写字母。
如果指定了精度,则输出的数字不足时在左侧补0。
默认精度为1。
精度为0且值为0,则输出为空。
o 8进制unsigned int。
如果指定了精度,则输出的数字不足时在左侧补0。
默认精度为1。
精度为0且值为0,则输出为空。
s 如果没有用l标志,输出null结尾字符串直到精度规定的上限;如果没有指定精度,则输出所有字节。
如果用了l标志,则对应函数参数指向wchar_t型的数组,输出时把每个宽字符转化为多字节字符,相当于调用wcrtomb函数。
c 如果没有用l标志,把int参数转为unsigne
d char型输出;如果用了l标志,把wint_t参数转为包含两个元素的wchart_t数组,其中第一个元素包含要输出的字符,第二个元素为null宽字符。
p void *型
a,A double型的16进制表示,"[−]0x h.hhhh p±d"。
其中指数部分为10进制表示的形式。
例如:1025.010输出为0x1.004000p+10。
'a'使用小写字母,'A'使用大写字母。
[2][3](C++11流使用hexfloat输出16进制浮点数)
n 不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
%'%'字面值,不接受任何flags, width, precision or length。
宽度与精度格式化参数可以忽略,或者直接指定,或者用星号"*"表示取对应函数参数的值。
例如printf("%*d", 5, 10)输出" 10";printf("%.*s", 3, "abcdef")输出"abc"。
如果函数参数太少,不能匹配所有的格式参数说明符,或者函数参数的类型不匹配,将导致未定义(undefined)行为。
过多的函数参数被忽略。
许多时候,未定义的行为将导致格式化字符串攻击。
某些编译器,如GCC,会静态检查printf这一类函数的格式化参数并编译警告存在的问题(当使用编译标志-Wall或-Wformat)。
GCC也会对用户自定义的printf 风格函数做静态检查,如果在函数定义时使用了非标准的"format" __attribute__。