c风格printf详解

发布时间 2023-06-28 17:34:40作者: 红笺无色

?

printf风格

C的字符标准流输出格式

格式如下:
%[flags][width][.precision][length]specifier

specifier

最后的识别字符,应该包括在以下的集合中,并且有如下的含义

格式说明符 输出描述 示例
d 或 i 带符号的十进制整数 392
u 无符号的十进制整数 7235
o 无符号的八进制数 610
x 无符号的十六进制整数(小写字母) 7fa
X 无符号的十六进制整数(大写字母) 7FA
f 十进制浮点数(小写字母) 392.65
F 十进制浮点数(大写字母) 392.65
e 科学计数法(尾数/指数,小写字母) 3.9265e+2
E 科学计数法(尾数/指数,大写字母) 3.9265E+2
g 使用较短表示:%e 或 %f 392.65
G 使用较短表示:%E 或 %F 392.65
a 十六进制浮点数(尾数/指数,小写字母) -0xc.90fep-2
A 十六进制浮点数(尾数/指数,大写字母) -0XC.90FEP-2
c 字符 a
s 字符串 sample
p 指针地址 b8000000
n 无输出
相应的参数必须为指向有符号整数的指针到目前为止写入的字符数存储在指定的位置中。
% % 后跟另一个 % 字符可将单个 % 写入流中。 %

flag

flags 描述
- 这个标志位 - 用于在给定的字段宽度内左对齐文本。默认情况下,文本是右对齐的。
+ 这个标志位 + 用于在结果前强制添加加号或减号(+ 或 -),即使对于正数也是如此。默认情况下,只有负数会被添加减号。
space 在值前方插入一个空格
# 这个标志位 # 在一些格式说明符(specifier)中使用时具有特定的效果:
在 o、x 或 X 格式说明符中使用:如果值不为零,则在前面加上 0、0x 或 0X。
例如,使用格式化字符串 %#o 和一个非零的八进制数值,如 42,将生成输出 "052",其中 0 是前缀,表示这是一个八进制数。
在 a、A、e、E、f、F、g 或 G 格式说明符中使用:即使没有更多数字,也会强制输出带有小数点。
默认情况下,如果没有数字紧随其后,则不会写入小数点。
例如,使用格式化字符串 "%#.2f" 和一个整数 42,将生成输出 "42.00",即使只有两位小数。
0 这个标志位 0 在指定填充宽度时,用零(0)而不是空格进行左填充数字。默认情况下,使用空格进行填充。
例如,假设有以下格式化字符串:"%05d"。这里的 0 标志指示使用零进行左填充,并且字段宽度为 5。如果要格式化一个整数 42,则输出将是 "00042",因为使用零进行了左填充以满足宽度要求。

值得注意的是flag位只占一位,因此不会和后续的width部分冲突

width

width 描述
(number) 用于指定最小要打印的字符数。如果要打印的值比这个数字要短,那么结果将用空格进行填充。即使结果更大,也不会截断值。
* 表示后续读取时需要额外读入一个宽度参数。
例如printf("%*d", width, value);

.precision

.precision 描述
.number 对于整数型说明符(d、i、o、u、x、X):精度指定要输出的最小数字位数。如果要输出的值比该数字短,则用前导零填充。即使结果更长,值也不会被截断。精度为 0 表示值为 0 时不输出字符。
a、A、e、E、f 和 F 说明符:这是小数点后要打印的位数(默认为 6)
g 和 G 说明符:这是要打印的最大有效数字位数
s 说明符:这是要打印的最大字符数。默认情况下,打印所有字符,直到遇到终止的空字符。
如果没有显式指定精度的值为 0.
.* 精度不在格式字符串中指定,而是作为一个额外的整数值参数在格式化的参数之前提供。

length

length子说明符用于修改数据类型的长度,需要与sepecifiers结合使用。

下面是一个图表,显示了用于解释相应参数的类型及是否使用length说明符(如果使用不同类型,则执行适当的类型提升或转换,如果允许的话):

sepecifiers
length d i u o x X f F e E g G a A c s p n
(none) int unsigned int double int char* void* int*
hh signed char unsigned char signed char*
h short int unsigned short int short int*
l long int unsigned long int wint_t wchar_t* long int*
ll long long int unsigned long long int long long int*
j intmax_t uint_max_t intmax_t*
z size_t size_t size_t*
t ptrdiff_t ptrdiff_t ptrdiff_t*
L long double

其中蓝色部分为C99引入的specifiers和sub-specifiers。

例子

/* printf example */
#include <stdio.h>

int main()
{
   printf ("Characters: %c %c \n", 'a', 65);
   printf ("Decimals: %d %ld\n", 1977, 650000L);
   printf ("Preceding with blanks: %10d \n", 1977);
   printf ("Preceding with zeros: %010d \n", 1977);
   printf ("Some different radices: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
   printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
   printf ("Width trick: %*d \n", 5, 10);
   printf ("%s \n", "A string");
   return 0;
}

Output:

Characters: a A
Decimals: 1977 650000
Preceding with blanks:       1977
Preceding with zeros: 0000001977
Some different radices: 100 64 144 0x64 0144
floats: 3.14 +3e+000 3.141600E+000
Width trick:    10
A string

参考

  1. cplusplus官方文档