printf是一套家族函数,是C语言标准库函数,定义于头文件stdio.h,其定义如下所示:
1
2
3
4
5
6
7
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int dprintf(int fd, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
printf的format参数是格式控制字符串,它包含两种字段:一是普通字符串,打印时原样输出;二是控制字段,打印时使用可变变量…指定的参数数据,来替换对应的控制字段。两种字段相结合,形成结果字符串,然后printf将结果字符串打印到标准输出。
格式化字符串
printf的控制字段,通用格式定义如下,其中[]中的部分是可选项:
%[flags][width][.precision][length]specifier 即: %[标志][最小宽度][.精度][类型长度]说明符
specifier
specifier亦即说明符,为必选项,其规范如下:
specifier | 对应数据类型 | 说明 | 例子 |
---|---|---|---|
d/i | int | 有符号十进制整数,i是老式写法 | 392 |
u | unsigned int | 无符号十进制整数 | 7235 |
o | unsigned int | 无符号八进制整数,无前导0 | 610 |
x | unsigned int | 无符号十六进制整数,小写,无前导0x后者0X | 7fa |
X | unsigned int | 无符号十六进制整数,大写,无前导0x后者0X | 7FA |
f/lf | double | 十进制浮点数,默认精度为6(lf在C99开始加入标准,意思和f相同) | 392.65 |
e | double | 科学计数法表示的数,小写,默认浮点数精度为6 | 3.9265e+2 |
E | double | 科学计数法表示的数,大写,默认浮点数精度为6 | 3.9265E+2 |
g | double | 根据数值不同自动选择%f或%e,%e格式在指数小于-4或指数大于等于精度时用使用 | 392.65 |
G | double | 根据数值不同自动选择%f或%E,%E格式在指数小于-4或指数大于等于精度时用使用 | 392.65 |
a | double | 十六进制浮点数,小写 | -0xc.90fep-2 |
A | double | 十六进制浮点数,大写 | -0XC.90FEP-2 |
c | char | 字符,可以按照ASCII码的数字转换为对应的字符 | a |
s | char * | 字符串,输出字符串中的字符以'\0'结尾或者打印由精度指定的字符数 | sample |
p | void * | 十六进制形式输出指针 | b8000000 |
n | int * | 到此字符之前为止,一共输出的字符个数,不输出文本 | |
% | 不转换参数 | 不进行转换,输出字符‘%’(百分号)本身 |
flags
flags亦即标志,为可选项,其规范如下:
flags | 字符名称 | 说明 |
---|---|---|
- | 减号 | 在给定的字段宽度内左对齐,右边填充空格(默认右对齐) |
+ | 加号 | 强制在结果之前显示加号或减号(+或-),默认情况下,只有负数前面会显示 - 号 |
(space) | 空格 | 输出值为正时加上空格,为负时加上负号 |
# | 井号 | 根据specifier加前缀:o、x、X 时,加前缀0、0x、0X;e、E、f、g、G 时,一定使用小数点;g、G 时,尾部的0保留 |
0 | 数字零 | 对于所有的数字格式,使用前导零填充字段宽度(如果出现了减号标志或者指定了精度,则忽略该标志) |
width
width亦即最小宽度,为可选项,用于控制当前字段的显示宽度,其规范如下:
width | 字符名称 | 说明 |
---|---|---|
digit(n) | 数字 | 字段显示宽度的最小值 如果输出的字段长度小于该数,结果会用前导空格填充; 如果输出的字段长度大于该数,结果使用更宽的字段,不会截断输出。 |
* | 星号 | 宽度在format字符串中的规定位置未指定,使用星号表示附加参数,指示下一个参数是width |
示例程序:
1 |
|
示例程序执行结果输出如下:
.precision
.precision亦即精度,为可选项,用于指定输出精度,其规范如下:
.precision | 字符名称 | 说明 |
---|---|---|
.digit(n) | 点+数字 | 对d/i/o/u/x/X:指定要打印的数字的最小位数。 如果写入的值短于该数,结果用前导数0来填充; 如果写入的数长于该数,结果不会截断; 如果为0,表示不写入任何字符。 对e/E/f:要在小数点后输出的小数位数; 对g/G:要输出的最大有效位数;
对s:要输出的最大字符数。 如果字符串实际长度大于该精度,则按该精度显示字符串,亦即截断; 如果小于,按原字符串实际长度输出。
对c:没有任何影响;
当未指定任何精度时,默认为 1。如果指定时只使用点而不带有一个显式值,则标识其后跟随一个 0。 |
.* | 点+星号 | 精度在 format 字符串中规定位置未指定,使用点+星号标识附加参数,指示下一个参数是精度 |
示例程序:
1 |
|
length
length亦即类型长度,用于控制待输出数据的数据类型长度,其规范如下:
length | d/i | u/o/x/X | f/F/e/E/g/G/a/A | c | s | p | n |
---|---|---|---|---|---|---|---|
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 | uintmax_t | intmax_t* | ||||
z | size_t | size_t | size_t* | ||||
t | ptrdiff_t | ptrdiff_t | ptrdiff_t* | ||||
L | long double |
备注:intmax_t/uintmax_t,表示在某系统中最大宽度整数类型。在64位系统中,如此定义:
1 | typedef long long intmax_t; |