是什么
📚 <stdio.h> 是 C 语言的“嘴巴和耳朵”——负责把数据输出到屏幕、从键盘读取数据、以及读写文件。几乎每个 C 程序都离不开它。
💡 生活比喻:把程序想象成一个人。printf 是“说话”,scanf 是“听”,getchar/putchar 是“一个字一个字地读和写”,fgets 则是“安全地读一整行”。
⚠️ 注意:本节只讲最常用的控制台输入输出函数;文件操作请见 1.2 文件操作,完整清单请见 15.1 <stdio.h>。
printf(fmt, ...) —— 格式化输出到屏幕
🎯 功能:接受一个格式字符串 fmt 和若干参数,按照格式说明符把它们转换成文本并打印到标准输出。
💡 比喻:就像填空题模板:"姓名: %s, 年龄: %d" 是模板,后面的变量就是答案,printf 帮你把答案填进去并念出来。
🔧 声明:int printf(const char *format, ...);
↩️ 返回值:成功输出的字符数(不含结尾 \0);出错返回负值。
#include <stdio.h>
int main() {
int age = 20;
double score = 95.5;
char name[] = "Tom";
printf("姓名: %s\n", name);
printf("年龄: %d\n", age);
printf("分数: %.1f\n", score);
printf("Hex: 0x%X\n", 255);
return 0;
}scanf(fmt, &...) —— 从键盘读数据
🎯 功能:接受格式字符串和变量地址(注意加 &),按格式从标准输入读取数据并写入对应变量。
💡 比喻:就像快递分拣员:根据订单格式(%d、%lf、%s)把键盘输入的“包裹”分发到不同变量里。忘记写 & 就像把包裹扔到空气里,程序会崩溃。
🔧 声明:int scanf(const char *format, ...);
↩️ 返回值:成功读取并赋值的项数;遇到输入结束或匹配失败可能提前返回。
#include <stdio.h>
int main() {
int a, b;
printf("请输入两个整数(空格隔开): ");
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n", a, b, a + b);
return 0;
}getchar() / putchar(c) —— 单字符读写
🎯 功能:getchar() 从标准输入读取一个字符;putchar(c) 把字符 c 写到标准输出。
💡 比喻:就像打字机:按一下键 getchar() 读一个字,敲一下字模 putchar() 打出一个字。
🔧 声明:int getchar(void); int putchar(int c);
↩️ 返回值:getchar 返回读到的字符(用 int 表示,以便容纳 EOF);putchar 返回写入的字符,出错返回 EOF。
#include <stdio.h>
int main() {
int c;
printf("输入字符,按 Ctrl+Z 结束:\n");
while ((c = getchar()) != EOF) {
putchar(c); // 原样回显
}
return 0;
}puts(s) / fputs(s, stream) —— 输出字符串
🎯 功能:puts(s) 把字符串 s 写到屏幕并自动换行;fputs(s, stream) 写到指定流,不自动换行。
💡 比喻:puts 像“自动按回车的喊话器”;fputs 像“写黑板”,写完不自动换行,方便你继续在同一行追加内容。
🔧 声明:int puts(const char *s); int fputs(const char *s, FILE *stream);
↩️ 返回值:成功返回非负值;出错返回 EOF。
#include <stdio.h>
int main() {
puts("Hello World"); // 自动换行
fputs("Hello ", stdout); // 不换行
fputs("World\n", stdout); // 手动换行
return 0;
}fgets(s, n, stream) —— 安全读取一行
🎯 功能:从 stream 最多读取 n-1 个字符到缓冲区 s,遇到换行或文件结束就停止,并自动加字符串结束符 \0。
💡 比喻:就像用有刻度尺的杯子接水:最多接 n-1 毫升,满了就停,绝不会溢出来,比危险的 gets 安全得多。
🔧 声明:char *fgets(char *s, int n, FILE *stream);
↩️ 返回值:成功返回 s;到达文件尾或出错返回 NULL。
#include <stdio.h>
int main() {
char line[256];
printf("请输入一行:");
fgets(line, sizeof(line), stdin); // 安全读取一行
printf("你输入的是:%s", line);
return 0;
}sprintf / snprintf —— 格式化到字符串
🎯 功能:把格式化的结果写进字符数组而不是屏幕。sprintf 不检查长度,snprintf 带长度限制,是更安全的选择。
💡 比喻:就像把要说的话先写在纸条上,而不是直接喊出来。snprintf 的纸条大小固定,写不下会自动截断,不会把墨水洒到外面。
🔧 声明:int snprintf(char *s, size_t n, const char *format, ...);
↩️ 返回值:返回“如果空间足够”会写入的字符数(不含 \0),截断时返回值 ≥ n。
#include <stdio.h>
int main() {
char buf[64];
int n = 20;
snprintf(buf, sizeof(buf), "n 的平方是 %d", n * n);
printf("%s\n", buf); // n 的平方是 400
return 0;
}sscanf(s, fmt, ...) —— 从字符串解析数据
🎯 功能:和 scanf 类似,但不是从键盘读,而是从字符串 s 里按格式提取数据。
💡 比喻:就像从一张已经写好的纸条上提取信息。比如纸条写着 "2024 90.5",sscanf 能把它拆成年份和分数。
🔧 声明:int sscanf(const char *s, const char *format, ...);
↩️ 返回值:成功解析并赋值的项数。
#include <stdio.h>
int main() {
const char *info = "2024 90.5";
int year;
double score;
sscanf(info, "%d %lf", &year, &score);
printf("年份=%d, 分数=%.1f\n", year, score);
return 0;
}&,否则是未定义行为。
2. %s 遇空格停止,且要给出缓冲区大小,如 %63s,防止溢出。
3. 读完整行应优先用 fgets,而不是 gets(已废弃)。%d 整数、%u 无符号、%f 浮点、%c 字符、%s 字符串、%p 指针、%x 十六进制、%% 百分号本身。👉完整 <stdio.h> 函数清单(fopen/fread/fwrite/sprintf/snprintf 等 40+)→