Back to Top

printf 家族

printf函数家族用于创建格式化的输出。 标准: 7.19.6.1

printf函数家族的格式代码和scanf函数家族的格式代码用法不同。所以必须小心谨慎,防止误用。 两者的格式代码中的有些可选字段看上去是相同的,这使得问题变得更为困难。 《C和指针》

函数成员

printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf, 
wprintf, fwprintf, swprintf, vwprintf, vfwprintf, vswprintf, 

格式代码

%[flags] [width] [.precision] [{hh | h | l | ll | j | z | t | L}]type

格式代码由一个百分号开头,后面跟 参考MSDN

  1. 零个或者多个 标志字符[flags],用于修改有些转换的执行方式 参考MSDN
  2. 一个可选的 最小字段宽度[width] 参考MSDN
  3. 一个可选的 精度[.precision] 参考MSDN
  4. 一个可选的 修改符 [{hh | h | l | ll | j | z | t | L}] 参考MSDN
  5. 转换类型 type 参考MSDN

转换类型 type

Character Type Output format
c,C int 用于printf时,为单字节;用于wprintf时,为宽字节.
d,i int 有符号十进制数.
u,o,x,X unsigned 无符号数值. 十进制:u; 八进制:o; 十六进制:x,X, 两者区别, x是abcdef, X使用ABCDEF.
e,E double 指数形式输出.如:6.023000e23是使用e;6.023000E23是使用E. 小数点后面的位数由精度字段决定,默认为6
f,F double 常规浮点数格式输出.如:[–]dddd.dddd. 小数点后面的位数由精度字段决定,默认为6
g,G double 自动选择使用%f,%e,%E. 如果指数大于等于-4但小于精度字段使用%f,否则使用%e(g->e, G->E)
a,A double 有符号的十六进制双精度浮点值[?]0xh.hhhh p±dd, 其中h.hhhh为十六进制的尾数, dd为指数
s char* 用于printf时,为单字节字符串;用于wprintf时,为宽字节字符串. 长度为字符串长度或者精度.(wcrtomb转码)
S char* 用于printf时,为宽字节字符串;用于wprintf时,为单字节字符串. 长度为字符串长度或者精度.(VS)
P void* 指针值转换为因编译器而异的可打印字符.(VS:十六进制数字)
n int* 无输出,返回到目前为止函数所产生的的输出字符数保存在该指针所指向的内存中(VS中默认禁用,使用_set_printf_count_output(1)开启)
%   输出一个%字符

hs在用于wprintf时,存在字符集问题。

VS需要设置 setlocale(LC_ALL, "");

GCC需要设置编译参数 gcc Test.cpp -finput-charset=gbk

setlocale(LC_ALL, "");
wprintf(L"%hs \n", "abc");
wprintf(L"%hs \n", "陈");

格式标志[flags]

Flag Meaning Default
- 值在字段中左对齐 右对齐
+ 对于格式化有符号的值时,对于非负值,强制加正号 非负值,不显示正号
0 当数值为右对齐时,用0填充未使用的列 用空格填充
空格 当有符号的数值为非负时,在其开始位置添加一个空格 不添加空格
# 选择某些类型的另一种转换形式(见下表)  
  • 0标志
    • 可用于 d,iu,o,x,X,E,f,g,G 。使用 d,i,u,o,x,X 类型(type)时,如果给出了精度(如:%04.d),0标志就被忽略。
    • 如果代码中出现了负号标志,0标志也没有效果
  • 空格标志
    • 和正号标志是互斥的,如果两个同时给出,空格标志将被忽略。
用于.. #标志
o 保证产生的值以一个零开头
x,X 在非零值前面加0x前缀(%X则为0X)
e,E,f,(a,A) 确保结果始终包含一个小数点,即使他后面没有数字
g,G 和上面的e,E,f相同。另外,缀尾的0并不从小数中去除
c,d,i,u,s 忽略该标志

字段宽度[width]

字符宽度是一个十进制数,用于指定将出现在结果中的 最小字符数.如果值得字符数少于字段宽度,就会对它填充以增加长度. flags决定填充是用空白字符还是零以及它出现在值的左边还是右边.

字段精度[.precision]

精度已一个 句点(.) 开头,后面是一个可选的十进制整数. 如果未给出整数,精度缺省值为零

对于d,u,u,o,x,X类型的转换,精度字段制定将出现在结果中的 最小数字的个数 并覆盖零标志. 如果转换后的值的位数小于宽度,就在它的前面插入零. 如果值为零且精度也为零,则转换结果就不会产生数字.

对于e,E,f类型的转换,精度决定将出现在 小数点之后的数字位数 .

对于g,G类型的转换,它制定将出现在结果中的 最大 有效位数.

当使用s类型转换时,精度指定将被转换的 最多 的字符数.

如果用于表示字段宽度 和/或 精度的十进制整数由一个 *星号()** 代替, 那么printf的下一个参数(必须是个整数)就提供宽度 和/或 精度. 因此这些值可以通过计算活动而不必预先设定.

printf("%.*s \n", 3, "abcdef"); // abc  (相当于%.3s)
printf("%0*s \n", 5, "abc"); // 00abc  (相当于%05s)
printf("%0*.*s \n", 5, 3, "abcdef"); // 00abc  (相当于%05.3s)

修改符[{hh | h | l | ll | j | z | t | L}]

C99

To specify Use prefix With type specifier Compiler
signed char hh d, i, o, x, or X GCC
unsigned char hh o, u, x, or X GCC
short int h d, i, o, x, or X GCC VS
unsigned short int h o, u, x, or X GCC VS
long int l (lowercase L) d, i, o, x, or X  
unsigned long int l o, u, x, or X  
wint_t l c  
wchar_t l s  
long long int ll d, i, o, x, or X  
unsigned long long int l o, u, x, or X  
long double l or L a, A, e, E, f, f, g, or G  

l 修改符 对 a, A, e, E, f, F, g,or G 类型 无效。

j (GCC)

Specifies that a following d, i, o, u, x,or X conversion specifier applies to
an intmax_t or uintmax_t argument; or that a following n conversion
specifier applies to a pointer to an intmax_t argument.
表明接下来的d,i,o,u,x或X转换说明符会应用于intmax_t或uintmax_t参数,
或者表明接下来的转换说明符n会应用于一个只想intmax_t参数的指针

z (GCC)

Specifies that a following d, i, o, u, x,or X conversion specifier applies to a
size_t or the corresponding signed integer type argument; or that a
following n conversion specifier applies to a pointer to a signed integer type
corresponding to size_t argument.
表明接下来的转换说明符d,i,o,,u,x或X会应用于一个size_t或对应的有符号整数类型的参数;
或者表明接下来的转换说明符n会应用于一个指针,该指针指向一个对应于size_t类型的参数的有符号整数类型

t (GCC)

Specifies that a following d, i, o, u, x,or X conversion specifier applies to a
ptrdiff_t or the corresponding unsigned integer type argument; or that a
following n conversion specifier applies to a pointer to a ptrdiff_t
argument.	
表明接下来的转换说明符d,i,o,,u,x或X会应用于ptrdiff_t或相应的无符号整数类型的参数;
或者表明接下来的n会应用于一个指向ptrdiff_t类型的参数的指针

MS VC++

数值类型

To specify Use prefix With type specifier
long int l (lowercase L) d, i, o, x, or X
long unsigned int l o, u, x, or X
long long ll d, i, o, x, or X
short int h d, i, o, x, or X
short unsigned int h o, u, x, or X
__int32 I32 d, i, o, x, or X
unsigned __int32 I32 o, u, x, or X
__int64 I64 d, i, o, x, or X
unsigned __int64 I64 o, u, x, or X
ptrdiff_t I d, i, o, x, or X
size_t I o, u, x, or X
long double l or L f
ptrdiff_t 
	(that is, __int32 on 32-bit platforms, __int64 on 64-bit platforms)	
size_t 
	(that is, unsigned __int32 on 32-bit platforms, unsigned __int64 on 64-bit platforms)

字符类型

To specify Use prefix With type specifier
Single-byte character with printf functions h c or C
Single-byte character with wprintf functions h c or C
Wide character with printf functions l c or C
Wide character with wprintf functions l c or C
Single-byte – character string with printf functions h s or S
Single-byte – character string with wprintf functions h s or S
Wide-character string with printf functions l s or S
Wide-character string with wprintf functions l s or S
Wide character w c
Wide-character string w s

字符类型等同于

To print character as Use function With format specifier
single byte printf c, hc, or hC
single byte wprintf C, hc, or hC
wide wprintf c, lc, lC, or wc
wide printf C, lc, lC, or wc