printf() 和 scanf() 大家都会用,但格式符的门道远不止 %d 和 %f。占位符里夹的那些数字、点、负号,能精确控制对齐、宽度、精度。下面把它们一个个拆开看。

格式符是什么

格式符以 % 开头,告诉 printf()/scanf() 拿到的数据按什么类型解释、怎么排版。一套最小例子:

#include <stdio.h>

int main() {
    int age = 25;
    float salary = 45000.50;
    char grade = 'A';

    printf("Age: %d\n", age);          // Age: 25
    printf("Salary: %.2f\n", salary);  // Salary: 45000.50
    printf("Grade: %c\n", grade);      // Grade: A
    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 基本等价 */

无符号整数 %u

给 %u 传负数,它会按二进制的补码解释,打出很大的正数:

unsigned int var;
scanf("%u", &var);
printf("Unsigned Integer: %u\n", var);   // 3
printf("Printing -10 using %%u: %u\n", -10);  // 4294967286

浮点 %f、%e、%E

float a = 12.67;
printf("Using %%f: %f\n", a);   // 12.670000
printf("Using %%e: %e\n", a);   // 1.267000e+01(科学计数法)
printf("Using %%E: %E", a);     // 1.267000E+01

八进制 %o 与十六进制 %x / %X

int a = 67;
printf("%o\n", a);   // 103

int b = 15454;
printf("%x\n", b);   // 3c5e(小写)
printf("%X", b);     // 3C5E(大写)

字符串 %s

printf 里 %s 直接把字符串打完;scanf 里 %s 读到第一个空白就停,带空格的句子会被截断:

char str[50];
scanf("%s", str);        /* 输入 "Hi Bob" 只拿到 "Hi" */
printf("Entered String: %s", str);

想读整行带空格,用 fgets() 或者扫描集 %[ ]。

地址 %p

int a = 10;
printf("The Memory Address of a: %p", (void*)&a);  // 0x7ffe6f71e60c

长整型们

格式符类型
%ld / %lilong
%lfdouble
%Lflong double
%luunsigned long
%lld / %llilong long
%lluunsigned long long

排版三件套:宽度、对齐、精度

在 % 和格式符之间可以插修饰:

  • 数字 = 最小字段宽度,不够宽用空格补齐,超了不截断。
  • - 号 = 左对齐(默认右对齐)。
  • .数字 = 精度:整数指最少位数,字符串指最多字符数,浮点指小数位数。

一套对比最直观:

#include <stdio.h>

int main() {
    char str[] = "online-compiler";
    printf("%20s\n", str);     /* 右对齐,宽 20 */
    printf("%-20s\n", str);    /* 左对齐,宽 20 */
    printf("%20.5s\n", str);   /* 宽 20,只取前 5 个字符,右对齐 */
    printf("%-20.5s\n", str);  /* 宽 20,只取前 5 个字符,左对齐 */
    return 0;
}

输出:

     online-compiler
online-compiler
              online
online

浮点的精度最常见:%.2f 保留两位小数。

完整速查表

格式符含义
%c字符
%d / %i有符号整数
%u无符号整数
%ffloat
%lfdouble
%Lflong double
%e / %E科学计数法浮点
%g / %G按当前精度选 %f 还是 %e
%o八进制
%x / %X十六进制(小写/大写)
%s字符串
%p指针地址
%ldlong
%lldlong long
%%输出一个百分号 %

几个易错点

  • 类型要配:%d 配 int、%f 配 float、%lf 配 double,配错是未定义行为。
  • scanf 要取地址scanf("%d", &x),字符串除外(数组名本身就是地址)。
  • 想打印 %:写 %%
  • scanf 的 %s 停空格:要读整行换 fgets()。

格式符是 C 语言里输出想好看、输入想稳的基本功,多写几遍就熟了。