printf()函数提供丰富的占位符参数以便精细地控制输出格式。这些精细的控制在日常编程中用得不多,毕竟大部分的应用程序都是基于图形界面,而不是终端的。考虑到部分OJ系统中的在线编程题可能对输出格式作了精细要求,这里对printf()函数的格式化输出控制进行“详细”讨论。
1. 简单的printf()语法
1 | //Project - Variable |
上述代码的执行结果为:
1 | 3 apples, 3.6 for each, 10.80 in total. |
上述程序及图1展示了通过printf()进行格式化输出的最基本方法。程序中的printf( )函数共有4个参数,其中,第1个参数由双引号包裹,是一个字符串。该字符串中包含了三个占位符(place holder),在格式化输出过程中,这些占位符将依次由后续参数的值替换。图1展示了该行的各占位符、参数与输出文本之间的对应关系。
printf( )函数可以接受多个参数,其第1个参数预期为一个字符串,该字符串中的占位符个数以及要求的类型应与后续其他参数相匹配,否则会产生错误。最简单的占位符由一个%加上一个specifier说明符构成,specifier说明符详见表1。
2. 运用复杂占位符进行格式化输出
2.1 完整的占位符语法
一个完整的占位符格式如下,其中,[ ]表示其中的内容为可选项。在下述格式中,从前住后依次是%、标志(flags)、输出宽度(width)、精度(.precision)、类型长度(length)以及说明符(specifier)。其中,%以及末尾的specifier都是必需的。
1 | %[flags][width][.precision][length]specifier |
specifier说明符处于一个占位符的末尾,是占位符不可或缺的组成部分,它定义了printf()函数以何种类型来解释和输出与占位符匹配的参数。
说明符 | 输出 | 示例 |
---|---|---|
d或i | 有符号的十进制整数 | 827 |
u | 无符号的十进制整数 | 2353 |
o | 无符号八进制整数 | 621 |
x | 无符号十六进制整数(小写) | 2fb |
X | 无符号十六进制整数(大写) | 2FB |
f或F | 十进制浮点小数(小写) | 792.45 |
e | 科学计数法(小写) | 7.9245e+2 |
E | 科学计数法(大写) | 7.9245E+2 |
g | 以%e或%f中的较短格式输出浮点数 | 792.45 |
G | 以%E或%F中的较短格式输出浮点数 | 792.45 |
a | 十六进制浮点数(小写) | 0xd.1f |
A | 十六进制浮点数(大写) | 0XD.1F |
c | 单个字符 | z |
s | 字符串 | hello |
p | 指针(地址) | c280000000000000 |
n | 输出计数 格式化输出内容为空。当前为止已格式化输出的字符总数将存储在对应的参数中,该对应参数的类型应为int*。 |
|
% | 两个连续的%%将会在输出结果中产生一个%。 | % |
flags | 描述 |
---|---|
- | 在给定的输出宽度中左对齐,默认右对齐 |
+ | 对于正数,前置一个+号,对负数,前置一个-号。默认情况下,负数前置一个-号,正数前无+号。 |
(空格) | 如果数值前无符号位,插入一个空格在数值前。 |
# | 与%o, %x, %X配用时,在数值前分别附加0, 0x, 0X… |
0 | 当给定输出宽度时,如果数字的字符数不够,左边补0而不是空格。 |
width/输出宽度 | 描述 |
---|---|
(number) | 格式化输出的最小字符宽度。如果值格式化后的宽度小于指定宽度,则以空格填充。如果值格式化后实际宽度大于指定宽度,按实际值输出。 |
* | *号表示宽度值未在格式字符串中给出,而是作为一个附加的整数值列于被格式化输出的参数之前。 |
.precision/精度 | 描述 |
---|---|
.number | 对于整型说明符(d, i, o, u, x, X),该精度给出了最小的输出位数大小。如果实际值小于指定位数,则在前面补0。如果实际值位数大于指定位数,按实际值输出。如果指定精度为0,意为对于值0,格式化输出结果为空。 对于a,A,e,E,f和F等浮点数输出格式,该精度值给出了小数点后的位数(默认为6)。 对于g和G输出格式,该精度值规定了最大输出位数。 对于s输出格式,该精度值规定了最大输出字符数。默认情况下,以0结尾的C风格字符串中的全部字符都会被输出,直到遇到表示末尾的0值字符。 |
* | *号表示精度值未在格式字符串中给出,而是作为一个附加的整数值列于被格式化输出的参数之前。 |
类型长度(length)项用于表示数据类型的长度。表5列出了当不同的[length]项与不同的[specifier]合用时所对应的输出参数的数据类型。
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 | uintmax_t | intmax_t* | ||||
z | size_t | size_t | size_t* | ||||
t | ptrdiff_t | ptrdiff_t | ptrdiff_t* | ||||
L | long double |
2.2 示例
2.2.1 格式化输出整数
示例中为方便观察,使用| |来标识输出宽度。
1 |
|
执行结果为:
1 | i = |+346|, j = |-346| |
2.2.2 格式化输出浮点数
示例中为方便观察,使用| |来标识输出宽度。
1 |
|
执行结果为:
1 | f = |+3.141593|, d = |-314.159265| |
2.2.3 格式化输出字符串
示例中为方便观察,使用| |来标识输出宽度。
1 |
|
执行结果为:
1 | |tomcat| |
参考资料: