函数语法
stdio.h文件中的定义:
1 2 | /* Write formatted output to stdout. */ int printf (const char *__restrict __format, ...) |
作用:将格式化好的结果写到标准输出
有两个参数:
第一个参数为字符串类型的指针常量(只读变量),表示需要输出的格式。
第二个参数 "..." 表示被格式化的变量或常量,可为多个值中间用 "," 隔开,每个参数的值应当与前面格式化字符串中的占位符类型和位置一一对应。
返回值为 int 类型,表示输出的字节数
格式语法
1 2 | %[flags][width][.precision][length]specifier %[标志][宽度][.精度][长度]类型 |
flags
标志 | 含义 |
---|---|
- | 指定被转换的参数在其字段内左对齐(默认为右对齐) |
+ | 指定在输出的数前面加上正负号 |
空格 | 如果第一个字符不是正负号,则在其前面加上一个空格 |
0 | 对于数值转换,当输出长度小于字段宽度时,添加前导0进行填充 |
# | 指定另一种输出形式: |
1. 如果转换字符为 o,则第一个数字为 0 | |
2. 如果转换字符为 x 或 X,则指定在输出的非 0 值前加 0x 或 0X | |
3. 对于转字符为 e, E, f, g, G 的情况,指定输出总是包含一个小数点, | |
另外对于转换字符为 g 或 G,还指定输出值尾部无意义的 0 将被保留 |
注意:flags可同时出现多个,并且没有顺序要求
下面通过示例说明
'-'
1 2 3 4 5 6 7 8 9 | // - 指定被转换的参数在其字段内左对齐(默认为右对齐) short a = 1; // 将变量a按照10个字符的宽度输出, 默认为右对齐 // 右对齐 printf("%10d ", a); // 加上 "-" 后, 左对齐 printf("%-10d ", a); |
输出
1 2 | 1 1 |
'+'
1 2 3 4 5 6 7 8 9 10 | // + 指定在输出的数前面加上正负号 short b = 1; printf("%d ", b); // b的值为1, 会将b的值前面隐藏的加号强制显示, 输出 +1 printf("%+d ", b); // -b的值为-1, 原样输出 -1 printf("%+d ", -b); |
输出
1 2 3 | 1 +1 -1 |
空格
1 2 3 4 5 6 7 8 | // 空格 如果第一个字符不是正负号,则在其前面加上一个空格 short d = -1; // d的第一个字符是负号, 原样输出-1 printf("% d ", d); // -d的值为1, 不带正负号, 输出 空格+1 printf("% d ", -d); |
输出
1 2 | -1 1 |
0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | // 0 对于数值转换,当输出长度小于字段宽度时,添加前导0进行填充 // 1. 数字 short e = 1; // e的值为1, 要求按照宽度为5输出, 不足的部分宽度内左边补0 // 所以输出 "00001" printf("%05d ", e); // 2. 字符 char f = 'a'; // 将字符型变量f按照宽度为5输出, 不足的部分宽度内左边 // 自动补空格, 所以输出 " a" printf("%5c ", f); // 3. 字符串 char *str = "blank"; // str的值为字符串, 需要按照宽度为10输出 // 不足的部分宽度内左边自动补空格, 所以 // 输出 " blank" // 注意: 字符串的结束字符 ' ' 不包含在内 printf("%10s ", str); // 4. 字符 ' ' char blk = ' '; // 打印字符 ' ', 按字符格式会输出 ''(空) // 按整型格式会输出 "0" printf("%c, %d ", blk, blk); char *blk2 = "hello "; // blk2的值包含字符 ' ', 以宽度为10输出 // 不足的部分宽度内自动补空格, 所以会输出 // " hello", 输出时 ' ' 没有被显示出来 printf("%10s ", blk2); // 包含两个 ' ', 输出结果跟上面一样 char *blk3 = "hello "; printf("%10s ", blk3); |
输出
1 2 3 4 5 6 | 00001 a blank , 0 hello hello |
'#'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // # 指定另一种输出形式(o, x或X, f, g或G, e或E) int g = 1000; // 依次按八进制, 十六进制格式输出 printf("%#od, %#xd, %#Xd ", g, g, g); // 将整数1e3, 1000按照科学计数法e, E整型格式输出 printf("%#ed, %#Ed, %#ed ", 1e3, 1e3, 1000); // 将浮点数1e-3, 0.001按照科学计数法e, E单精度类型格式输出 printf("%#ef, %#Ef, %#ef ", 1e-3, 1e-3, 0.001); // 将浮点数0.001按照单精度f单精度类型格式输出 printf("%#ff ", 0.001); // 将浮点数3.14按照双精度g或G双精度类型输出 printf("%#gg, %#GG ", 3.14, 3.14); |
输出
1 2 3 4 5 | 01750d, 0x3e8d, 0X3E8d 1.000000e+03d, 1.000000E+03d, 0.000000e+00d 1.000000e-03f, 1.000000E-03f, 1.000000e-03f 0.001000f 3.14000g, 3.14000G |
width
宽度是一个数值,用于指定最小字段的宽度,转换后的参数输出宽度至少要达到这个数值,如果参数的字符数小于该数值,则在参数左边(如果flags设置为 "-",要求左对齐的话则在右边)填充一些字符,填充字符通常为空格,但是如果flags设置为 0,则填充字符为数字 0 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* 宽度(width) */ char *ur = "human"; // 直接原样输出 printf("%s ", ur); // 以宽度为10输出, 同时宽度内右对齐, 左端补空格 printf("%10s ", ur); // 以宽度为10输出, 同时宽度内左对齐, 右段补空格 printf("%-10s ", ur); // 直接原样输出 printf("%d ", 2); // 以宽度为5输出, 同时宽度内右对齐, 左端补空格 printf("%5d ", 2); // 以宽度为5输出, 同时宽度内右对齐, 左端补0 printf("%05d ", 2); // 以宽度为5输出, 同时宽度内左对齐, 右端补空格 printf("%-5d ", 2); // 以宽度为5输出, 同时宽度内左对齐, 右端没有补0, // 实际补的是空格, 最后输出 "2 " printf("%-05d ", 2); |
输出
1 2 3 4 5 6 7 8 | human human human 2 2 00002 2 2 |
.precision
格式为 "[.precision]" 或 "[.精度]",通过 "." 分隔字段的宽度和精度
说明:
- 对于字符串,它指定打印的字符的最大个数
- 对于整数,它指定打印的数字位数(必要时可加填充位 0 已达到宽度要求)
- 对于转换字符为 e或E, f,它指定打印的小数点后的数字位数
- 对于转换字符为 g或G,它指定打印的有效数字位数
下面通过示例说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | /* .精度(.precision) */ // 字符串 // 按最大3个字符输出, 超出的部分会被截断丢弃 printf("%.3s ", "abcdefg"); // 按最大5个字符输出, 小于最大字符个数不会补 // 空格也不会默认右对齐, 会原样输出 printf("%.5s ", "abc"); // 按最大5个字符输出, 小于最大字符个数不会补 // 空格也不会左对齐, 会原样输出 printf("%-.5s ", "abc"); // 整数 // 按照整数3位输出, 实际值是5位 // 大于3位, 会原样输出, 不会被截取 printf("%.3d ", 10000); // 按照整数5位输出, 实际值是3位 // 不够的位数会从左端开始补0 printf("%.5d ", 100); // e或E // 取小数点之后3位, 多出的部分被截取丢弃, 同时会四舍五入 printf("%.3e, %.3E ", 1.99991, 1.99991); // 取小数点之后5位, 不够的部分用0填充 printf("%.5e, %.5E ", -1.01, -1.01); // f // 取小数点之后3位, 多出的部分被截取丢弃, 同时会四舍五入 printf("%.3f ", 1.2689); // 取小数点之后5位, 不够的部分用0填充 printf("%.5f ", 1.26); // g或G // 按照3位数字位数输出, 多出的部分被截取丢弃, 同时会四舍五入 // 3代表的是数字位数 printf("%.3g, %.3G ", 2.888888, 2.888888); // 按照5位数字位数输出, 不够的部分不会补空格和0 // 5代表的是数字位数 printf("%.5g, %.5G ", 2.88, 2.88); |
输出
1 2 3 4 5 6 7 8 9 10 11 | abc abc abc 10000 00100 2.000e+00, 2.000E+00 -1.01000e+00, -1.01000E+00 1.269 1.26000 2.89, 2.89 2.88, 2.88 |
length
长度,可选的值为 h, hh, l, ll, L
- hh 表示将相应的参数按 signed char 或 unsigned char 类型输出
- h 表示将相应的参数按 short 或 unsigned short 类型输出
- l 表示将相应的参数按 long 或 unsigned long 类型输出
- ll 表示将相应的参数按 long long 或 unsigned long long 类型输出
- L 表示将相应的参数按 long double 类型输出
下面通过示例说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* 长度 length */ // hh signed char, unsigned char // 输出 ascii 65 对应的 A printf("%hhc ", 'x41'); printf("%hhc ", -1); // h short, unsigned short printf("%hd, %hd ", 1, -1); // l long, unsigned long printf("%ld, %ld ", 1, -1); // ll long long, unsigned long long printf("%lld, %lld ", 1, -1); // L long double printf("%Lg, %LG ", 1, -1); |
输出
1 2 3 4 5 6 | A ? 1, -1 1, 4294967295 1, 4294967295 -0, 5.12975E-4937 |
specifier
转换字符名 | 说明 |
---|---|
c | char 字符类型 |
d | int 有符号十进制整数 |
i | int 有符号十进制整数 |
e | double 以指数形式输出单精度,双精度浮点数(小写 e) |
E | double 以指数形式输出单精度,双精度浮点数(大写 e) |
f | double 以小数形式输出单精度,双精度浮点数 |
g | double 以 %f 或 %e 中较短的输出宽度输出单精度,双精度浮点数(指数显示小写e) |
G | double 以 %f 或 %e 中较短的输出宽度输出单精度,双精度浮点数(指数显示小写E) |
o | unsigned int 无符号八进制整数(无前导 0) |
s | char * 字符串 |
u | unsigned int 无符号十进制整数 |
x | unsigned int 无符号十六进制整数(无前导 0x) |
X | unsigned int 无符号十六进制整数(无前导 0X) |
p | void * 指针值 |
n | int * 存放已写字符的个数 |
% | 不进行参数转换,显示%自身 |
转义字符列表
转义字符 | 说明 | ASCII (十进制) |
---|---|---|
a | 响铃(BEL) | 7 |
退格(BS),将当前位置移到前一列 | 8 | |
f | 换页(FF),将当前位置移到下页开头 | 12 |
换行(LF),将当前位置移到下一行开头 | 10 | |
回车(CR),将当前位置移到本行开头 | 13 | |
水平制表(HT),(跳到下一个TAB位置) | 9 | |
v | 垂直制表(VT) | 11 |
代表一个反斜杠字符 | 92 | |
' | 代表一个单引号字符 | 39 |
'' | 代表一个双引号字符 | 34 |
? | 代表一个问号 | 63 |