格式控制符
格式控制符是C语言输入输出函数中的关键组成部分,用于指定数据的输入输出格式。它们与变量的存储类型密切相关,确保数据在内存与外部设备间正确转换。
常见格式控制符汇总
| 格式控制符 | 适用数据类型 | 输入时识别的字符 | 输出格式示例 |
|---|---|---|---|
%d |
有符号十进制整型 | +, -, 0-9 |
-123 |
%u |
无符号十进制整型 | 0-9 |
456 |
%o |
八进制整型 | 0-7 |
0173 |
%x / %X |
十六进制整型 | 0-9, a-f/A-F (可识别0x前缀) |
0x7b / 0X7B |
%f |
单精度浮点型 | +, -, 0-9, ., e/E |
3.141593 |
%lf |
双精度浮点型 | 同上 | 3.1415926536 |
%e / %E |
指数形式浮点数 | 同上 | 3.141593e+00 |
%g / %G |
自动选择%f或%e |
同上 | 3.14159 |
%c |
字符型 | 任意单个字符 | A |
%s |
字符串 | 非空白字符序列 | Hello |
%p |
指针地址 | - | 0x7ffeeb5d8c |
%% |
百分号本身 | - | % |
格式控制符工作原理
格式控制符在输入输出过程中起到数据类型转换的作用:
- 输入时:将外部字符序列按照指定格式解析,转换为内部二进制表示
- 输出时:将内部二进制数据按照指定格式转换为字符序列
例如:
c
int num;
scanf("%d", &num); // 输入"123",转换为整数123存储在内存中
printf("%d", num); // 将内存中的整数123转换为字符"123"输出
输入时格式控制符的特殊行为
%d、%u:自动跳过前导空白字符,读取连续的数字字符%c:读取下一个字符(包括空格、换行等空白字符)%s:读取连续的非空白字符 序列,自动添加\0%f、%lf:可识别小数点和科学计数法表示
输出函数
printf函数
基本格式
c
#include <stdio.h>
int printf(const char *format, ...);
format:格式控制字符串,包含普通字符和格式控制符...:可变参数列表,与格式控制符一一对应- 返回值:成功输出的字符数
格式控制符完整语法
%[标志][宽度][.精度][长度]类型
标志字符
| 标志 | 含义 | 示例 |
|---|---|---|
- |
左对齐 | %-10d |
+ |
显示正负号 | %+d |
空格 |
正数前加空格 | % d |
0 |
用0填充空白 | %08d |
# |
显示进制前缀 | %#x → 0x7b |
宽度与精度
c
int num = 123;
float f = 3.14159;
printf("%10d\n", num); // 宽度10,右对齐:" 123"
printf("%-10d\n", num); // 宽度10,左对齐:"123 "
printf("%010d\n", num); // 宽度10,用0填充:"0000000123"
printf("%.2f\n", f); // 保留2位小数:"3.14"
printf("%8.2f\n", f); // 宽度8,保留2位小数:" 3.14"
长度修饰符
| 修饰符 | 含义 | 示例 |
|---|---|---|
h |
short | %hd |
l |
long | %ld, %lf |
ll |
long long | %lld |
L |
long double | %Lf |
完整示例
c
#include <stdio.h>
int main() {
int a = 123;
float b = 3.14159;
char c = 'A';
char str[] = "Hello";
printf("十进制: %d\n", a);
printf("八进制: %o (带前缀: %#o)\n", a, a);
printf("十六进制: %x (大写: %X, 带前缀: %#x)\n", a, a, a);
printf("浮点数: %f (保留2位: %.2f)\n", b, b);
printf("指数形式: %e\n", b);
printf("自动选择: %g\n", b);
printf("字符: %c, ASCII: %d\n", c, c);
printf("字符串: %s\n", str);
printf("地址: %p\n", &a);
printf("百分号: %%\n");
return 0;
}
putchar函数
输出单个字符的简单函数:
c
#include <stdio.h>
int putchar(int c); // 返回输出的字符,失败返回EOF
示例:
c
putchar('A'); // 输出字符A
putchar('\n'); // 输出换行
putchar(65); // 输出ASCII码65对应的字符'A'
puts函数
输出字符串并自动添加换行:
c
#include <stdio.h>
int puts(const char *s); // 返回非负值表示成功,EOF表示失败
示例:
c
puts("Hello World!"); // 输出"Hello World!"并换行
注意:puts比printf效率高,但功能有限。
sprintf函数
将格式化字符串写入字符数组:
c
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
示例:
c
#include <stdio.h>
int main() {
char buffer[100];
int num = 123;
float fnum = 3.14159;
// 将格式化字符串写入buffer
int len = sprintf(buffer, "整数: %d, 浮点数: %.2f", num, fnum);
printf("写入内容: %s\n", buffer);
printf("写入长度: %d\n", len); // 不包括\0
return 0;
}
安全警告 :sprintf不会检查目标数组大小,可能导致缓冲区溢出。建议使用更安全的snprintf:
c
char buffer[20];
// 最多写入19个字符+1个\0
snprintf(buffer, sizeof(buffer), "数字: %d", 1234567890);
输入函数
scanf函数
基本格式
c
#include <stdio.h>
int scanf(const char *format, ...);
format:格式控制字符串...:变量地址列表(必须使用&取地址)- 返回值:成功读取并赋值的变量个数
输入格式控制
c
int a, b;
float f;
char c;
char str[20];
// 基本输入
scanf("%d", &a); // 输入整数
scanf("%f", &f); // 输入浮点数
scanf(" %c", &c); // 注意空格,跳过空白字符
scanf("%s", str); // 输入字符串(无空格)
// 多个输入
scanf("%d %f", &a, &f); // 用空格分隔
scanf("%d,%f", &a, &f); // 用逗号分隔(输入时也要用逗号)
scanf("%2d", &a); // 最多读取2位数字
// 抑制赋值
scanf("%*d %d", &a); // 跳过第一个整数,读取第二个
输入缓冲区机制
scanf不是直接从键盘读取,而是从输入缓冲区读取:
- 当用户输入数据并按下回车,数据进入输入缓冲区
scanf从缓冲区读取匹配格式的数据- 不匹配的数据或换行符会留在缓冲区
c
#include <stdio.h>
int main() {
int num;
char ch;
printf("请输入一个数字: ");
scanf("%d", &num); // 输入"123\n",读取123,\n留在缓冲区
printf("请输入一个字符: ");
scanf(" %c", &ch); // 空格跳过空白字符(包括\n)
printf("num=%d, ch=%c\n", num, ch);
return 0;
}
getchar函数
从标准输入读取单个字符:
c
#include <stdio.h>
int getchar(void); // 返回读取的字符,失败返回EOF
示例:
c
#include <stdio.h>
int main() {
printf("请输入一个字符: ");
int ch = getchar(); // 使用int接收,以便判断EOF
if (ch != EOF) {
printf("你输入的是: %c (ASCII: %d)\n", ch, ch);
}
// 清空输入缓冲区
while ((ch = getchar()) != '\n' && ch != EOF);
return 0;
}