printf 与 scanf 通过格式说明符(conversion specifier)指定实参的类型与输出样式。除基本的 %d、%f 外,还可使用宽度、对齐与精度等修饰符控制排版。变参函数如何解析这些说明符见变参函数一节。
格式说明符的作用
格式串中以 % 开头的说明符与后续实参一一对应(顺序与类型须匹配)。最小示例:
#include <stdio.h>
int main(void) {
int age = 25;
float salary = 45000.50f;
char grade = 'A';
printf("Age: %d\n", age);
printf("Salary: %.2f\n", salary);
printf("Grade: %c\n", grade);
return 0;
}常用说明符
字符 %c
char c;
scanf("%c", &c);
printf("The entered character: %c", c);有符号整数 %d 与 %i
int x;
scanf("%d", &x);
printf("Printed using %%d: %d\n", x);
printf("Printed using %%i: %i", x);%d 与 %i 用于 int 时语义相同。
无符号整数 %u
以 %u 输出负的 int 时,按无符号整型的位模式解释,可能得到很大的正数:
unsigned int var;
scanf("%u", &var);
printf("Unsigned Integer: %u\n", var);
printf("Printing -10 using %%u: %u\n", -10);浮点 %f、%e、%E
float a = 12.67f;
printf("Using %%f: %f\n", a);
printf("Using %%e: %e\n", a);
printf("Using %%E: %E", a);八进制 %o 与十六进制 %x / %X
int a = 67;
printf("%o\n", a);
int b = 15454;
printf("%x\n", b);
printf("%X", b);字符串 %s
printf 的 %s 输出以 \0 结尾的字符序列;scanf 的 %s 在遇到空白字符时停止,无法一次读入含空格的整行,整行读取可使用 fgets 或扫描集。
char str[50];
scanf("%s", str);
printf("Entered String: %s", str);指针地址 %p
int a = 10;
printf("The Memory Address of a: %p", (void*)&a);扩展整型与浮点
| 格式符 | 类型 |
|---|---|
%ld / %li | long |
%lf | double(多用于 scanf) |
%Lf | long double |
%lu | unsigned long |
%lld / %lli | long long |
%llu | unsigned long long |
宽度、对齐与精度
- 数字:最小字段宽度,不足时以空格填充(默认右对齐)。
-:左对齐。.数字:精度;对整数表示最少位数,对字符串表示最多输出字符数,对浮点表示小数位数。
#include <stdio.h>
int main(void) {
char str[] = "online-compiler";
printf("%20s\n", str);
printf("%-20s\n", str);
printf("%20.5s\n", str);
printf("%-20.5s\n", str);
return 0;
}输出:
online-compiler
online-compiler
online
online浮点数常用 %.nf 保留 n 位小数。
速查表
| 格式符 | 含义 |
|---|---|
%c | 字符 |
%d / %i | 有符号整数 |
%u | 无符号整数 |
%f | float(printf) |
%lf | double(scanf) |
%Lf | long double |
%e / %E | 科学计数法 |
%g / %G | 在 %f 与 %e 间自动选择 |
%o | 八进制 |
%x / %X | 十六进制 |
%s | 字符串 |
%p | 指针 |
%ld | long |
%lld | long long |
%% | 输出字面量 % |
常见错误
- 说明符与实参类型不匹配会导致未定义行为,例如用
%d输出double。 scanf中除字符串外,标量实参须传递地址:scanf("%d", &x)。- 输出字面量百分号应写
%%。 scanf("%s")遇空白停止;读整行应改用fgets等。
本节归纳了常用格式说明符与修饰规则。下一节讨论结构体内存对齐对对象大小的影响。