✍️ 作者:BackCatK Chen | 厦门市电子工程中级工程师
💻 专注C语言底层原理、嵌入式实战开发 | 持续更新保姆级入门教程
C语言的标准I/O是基于`文件操作体系,核心优势是"跨平台兼容+缓冲优化"------不管是Windows、Linux还是Mac,用标准I/O函数写的代码都能直接跑,而且默认的缓冲机制能提升读写效率。
很多新手学标准I/O时,会卡在"命令行参数怎么用""fopen打开失败怎么办""EOF到底是什么"这些问题上。这篇文章会按「检查命令行参数→fopen→getc/putc→文件结尾→fclose→标准文件指针」的顺序,每个模块都配 "生活场景+实战代码+逐行拆解+避坑指南",让你不仅知道"怎么用",还懂"为什么这么用",彻底告别"复制粘贴还报错"的尴尬!
一、检查命令行参数------ 给程序"传递文件指令" 📨
在标准I/O中,"检查命令行参数"是让程序灵活操作文件 的关键------比如你想让程序拷贝"a.txt"到"b.txt",不用每次修改代码里的文件名,直接在命令行输入 ./copy a.txt b.txt 就能实现。这背后就是命令行参数的作用!
1.1 核心概念:argc和argv是什么?
C语言程序的main函数支持两个参数,专门用于接收命令行输入的"指令",格式如下:
c
int main(int argc, char *argv[]) { ... }
- argc(argument count) :命令行参数的个数(包含程序名本身);
- argv(argument vector) :字符串数组,存储每个命令行参数的内容(argv[0]是程序名,argv[1]是第一个参数,argv[2]是第二个参数...)。
生活类比:
命令行参数就像"快递下单"------
- 程序名(argv[0])= 快递公司(如顺丰);
- 后续参数(argv[1]、argv[2])= 收件人地址、手机号(程序要操作的文件名、参数);
- argc = 下单时填写的"信息项个数"(含快递公司)。
实战演示:命令行参数的接收与检查
场景:写一个程序,通过命令行接收"待读取的文件名",然后读取文件内容。
c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// 第一步:检查命令行参数是否足够(至少需要 程序名 + 文件名 → argc≥2)
if (argc != 2) {
// 错误提示:告诉用户正确用法(argv[0]是程序名,比如./readfile)
fprintf(stderr, "❌ 参数错误!正确用法:%s 文件名>\n", argv[0]);
exit(1); // 异常退出,返回1表示出错
}
// 第二步:打印接收的参数(验证是否正确)
printf("✅ 程序名:%s\n", argv[0]);
printf("✅ 待读取文件:%s\n", argv[1]);
// 第三步:后续操作(打开文件、读取内容...后续模块详解)
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "❌ 无法打开文件:%s\n", argv[1]);
exit(1);
}
fclose(fp);
fp = NULL;
return 0;
}
运行方式(以Windows为例):
-
编译代码:
gcc readfile.c -o readfile.exe; -
命令行输入:
readfile.exe test.txt(test.txt是当前目录下的文件); -
正确输出:
✅ 程序名:readfile.exe ✅ 待读取文件:test.txt -
错误输入(参数不足):
readfile.exe,输出:❌ 参数错误!正确用法:readfile.exe 的文件名>
1.2 避坑指南(新手必看)
| 坑点 | 错误案例 | 解决方案 |
|---|---|---|
| 忘记检查argc | 直接用argv[1],参数不足时程序崩溃 | 先判断argc是否符合要求(如argc≥2),不符合则提示用法 |
| 混淆argv索引 | 把argv[0]当成文件名 | 记住:argv[0]是程序名,第一个参数从argv[1]开始 |
| 文件名路径错误 | 输入readfile.exe ../test.txt但文件不存在 |
提示用户检查文件路径(相对路径/绝对路径) |
| 用stderr输出错误 | 用printf输出错误信息 | 错误信息用fprintf(stderr, ...),避免被重定向掩盖 |
二、fopen()函数------ 打开文件的"钥匙" 🔑
fopen()是标准I/O的"入口函数"------所有文件操作都必须先通过fopen()建立程序与文件的关联,获取FILE*指针(文件的"唯一标识"),否则后续读写都无法进行。
2.1 函数原型与核心参数
c
FILE *fopen(const char *filename, const char *mode);
- filename :要打开的文件路径(相对路径如
"test.txt",绝对路径如"C:\\data\\test.txt"); - mode:文件打开模式(前两篇重点提过,这里做实战级详解);
- 返回值 :成功返回
FILE*指针(文件钥匙),失败返回NULL(必须检查!)。
2.2 关键:文件打开模式(实战常用版)
| 模式 | 类型 | 核心权限 | 适用场景 | 注意事项 |
|---|---|---|---|---|
"r" |
文本只读 | 只能读,文件必须存在 | 读取文本文件(.txt、.c) | 文件不存在则fopen返回NULL |
"w" |
文本只写 | 只能写,文件不存在则创建,存在则清空 | 新建/覆盖文本文件 | 会清空原有内容,慎用! |
"a" |
文本追加 | 只能写,文件不存在则创建,内容追加到末尾 | 写日志、添加数据 | 不会清空原有内容 |
"r+" |
文本读写 | 可读可写,文件必须存在 | 修改文本文件(如修改配置) | 不会清空原有内容 |
"rb" |
二进制只读 | 只能读二进制文件,文件必须存在 | 读取图片、视频、.dat | 二进制模式,无格式转换 |
"wb" |
二进制只写 | 只能写二进制文件,不存在则创建 | 存储结构体、数据块 | 会清空原有内容 |
生活类比:
"r"模式 = 打开已有的笔记本(只能看,不能改);"w"模式 = 买新笔记本(原有笔记本被扔掉,重新写);"a"模式 = 在笔记本末尾加页(不删原有内容,只加新的);"rb"模式 = 打开加密的U盘(原样读取,不解密)。
2.3 实战:fopen()打开文件+错误处理
场景 :通过命令行参数接收文件名,用"r"模式打开,处理所有可能的错误(文件不存在、路径错误、权限不足)。
c
#include error()函数必备(获取错误原因)
int main(int argc, char *argv[]) {
// 先检查命令行参数
if (argc != 2) {
fprintf(stderr, "❌ 用法:%s <文件名>\n", argv[0]);
exit(1);
}
// 打开文件(文本只读模式)
FILE *fp = fopen(argv[1], "r");
// 关键:检查fopen是否成功(fp是否为NULL)
if (fp == NULL) {
// strerror(errno):获取系统错误原因(需包含
fprintf(stderr, "❌ 打开文件失败!原因:%s\n", strerror(errno));
exit(1);
}
printf("✅ 文件打开成功!文件指针:%p\n", fp);
// 操作完成后关闭文件(后续模块详解)
fclose(fp);
fp = NULL; // 指针置空,避免野指针
return 0;
}
常见错误原因及输出:
- 文件不存在:
❌ 打开文件失败!原因:No such file or directory; - 权限不足(如Linux下文件为只读):
❌ 打开文件失败!原因:Permission denied; - 路径错误(如
"C:\\data\\test.txt"写成"C:data\test.txt"):❌ 打开文件失败!原因:No such file or directory。
2.4 避坑红黑榜
| 红榜(正确做法) | 黑榜(错误做法) | 后果 |
|---|---|---|
| 打开后检查fp == NULL | 直接用fp读写,不检查 | 文件打开失败时,fp为NULL,操作崩溃 |
| 二进制文件用"rb"/"wb" | 用"r"/"w"打开二进制文件 | 格式转换导致文件损坏(如图片无法打开) |
路径中Windows用双反斜杠\\ |
用单反斜杠\ |
编译器把\t当成制表符,路径错误 |
| 打开后及时关闭文件 | 打开后不关闭,一直占用资源 | 缓冲区数据丢失、系统文件描述符耗尽 |
三、getc()和putc()函数------ 逐字符读写的"基础工具" ✍️
getc()和putc()是标准I/O中最基础、最灵活的字符级读写函数------逐字符读取/写入文件,支持所有文本文件,还能处理字符级别的精细操作(如字符替换、统计)。
3.1 函数原型与核心逻辑
| 函数 | 原型 | 核心作用 | 返回值 |
|---|---|---|---|
| getc() | int getc(FILE *stream) |
从stream指向的文件中读取1个字符 | 成功返回字符的ASCII码(int类型),失败/文件结尾返回EOF |
| putc() | int putc(int c, FILE *stream) |
把字符c(ASCII码)写入stream指向的文件 | 成功返回字符c(int类型),失败返回EOF |
关键疑问:为什么返回值是int而不是char?
char类型范围是0~255(无符号)或-128~127(有符号);EOF(文件结尾/错误)的定义是-1,如果用char接收,-1会被转换成255,导致无法区分"字符255"和"EOF";- 用
int接收,既能存储所有字符的ASCII码,又能正确识别EOF(-1)。
3.2 实战1:用getc()读取文件并打印到屏幕
场景 :打开命令行参数指定的文件,逐字符读取并打印到控制台(类似cat命令)。
c
#include .h>
#include .h>
#include .h>
#include .h>
int main(int argc, char *argv[]) {
// 检查命令行参数
if (argc != 2) {
fprintf(stderr, "❌ 用法:%s n", argv[0]);
exit(1);
}
// 打开文件(文本只读)
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "❌ 打开失败:%s\n", strerror(errno));
exit(1);
}
printf("✅ 开始读取文件内容:\n");
int ch; // 必须用int接收getc()返回值
// 循环读取:直到getc()返回EOF(文件结尾/错误)
while ((ch = getc(fp)) != EOF) {
putchar(ch); // 打印到屏幕(stdout)
}
printf("\n✅ 读取完成!\n");
// 关闭文件
fclose(fp);
fp = NULL;
return 0;
}
3.3 实战2:用putc()逐字符写入文件
场景 :从键盘读取用户输入的字符串,逐字符写入到output.txt文件中(按Ctrl+Z(Windows)/Ctrl+D(Linux)结束输入)。
c
#include #include int main(void) {
// 打开文件(文本只写,不存在则创建)
FILE *fp = fopen("output.txt", "w");
if (fp == NULL) {
fprintf(stderr, "❌ 打开文件失败!\n");
exit(1);
}
printf("📝 请输入内容(按Ctrl+Z结束):\n");
int ch;
// 从标准输入(stdin=键盘)读取字符,写入文件
while ((ch = getchar()) != EOF) {
putc(ch, fp); // 写入到文件
}
printf("✅ 内容写入成功!\n");
fclose(fp);
fp = NULL;
return 0;
}
3.4 实战3:用getc()和putc()实现文件拷贝
场景 :通过命令行参数接收"源文件"和"目标文件",逐字符拷贝(类似copy命令)。
c
#include main(int argc, char *argv[]) {
// 检查参数:需要 程序名 + 源文件 + 目标文件 → argc=3
if (argc != 3) {
fprintf(stderr, "❌ 用法:%s argv[0]);
exit(1);
}
// 打开源文件(只读)和目标文件(只写)
FILE *fp_src = fopen(argv[1], "rb"); // 二进制模式,兼容所有文件
FILE *fp_dst = fopen(argv[2], "wb");
// 检查两个文件是否打开成功
if (fp_src == NULL) {
fprintf(stderr, "❌ 打开源文件失败:%s\n", strerror(errno));
exit(1);
}
if (fp_dst == NULL) {
fprintf(stderr, "❌ 打开目标文件失败:%s\n", strerror(errno));
fclose(fp_src); // 已经打开的源文件要关闭,避免资源泄漏
exit(1);
}
// 逐字符拷贝
int ch;
while ((ch = getc(fp_src)) != EOF) {
if (putc(ch, fp_dst) == EOF) { // 检查写入是否失败
fprintf(stderr, "❌ 写入目标文件失败!\n");
fclose(fp_src);
fclose(fp_dst);
exit(1);
}
}
printf("✅ 文件拷贝成功!源文件:%s → 目标文件:%s\n", argv[1], argv[2]);
// 关闭所有打开的文件
fclose(fp_src);
fclose(fp_dst);
fp_src = NULL;
fp_dst = NULL;
return 0;
}
3.5 避坑指南
- ❌ 用
char接收getc()返回值:ch = getc(fp)(char类型),无法识别EOF,导致无限循环; - ❌ 拷贝二进制文件用文本模式:
fopen(src, "r"),导致换行符转换,文件损坏(如图片、视频); - ❌ 不检查
putc()的返回值:写入失败(如磁盘满)时无法发现,导致拷贝不完整; - ✅ 二进制文件用
"rb"/"wb"模式:确保数据原样读写,兼容所有文件类型; - ✅ 循环条件用
(ch = getc(fp)) != EOF:先赋值再判断,避免漏读最后一个字符。
四、文件结尾(EOF)------ 识别文件的"终止信号" 🚦
在文件读写中,"文件结尾(EOF)"是程序判断"是否读完所有数据"的核心依据,但很多新手对EOF的理解存在误区------EOF不是文件中的某个字符,而是一个"状态标识"!
4.1 核心认知:EOF是什么?
- EOF(End Of File)的定义:
.h>中宏定义为#define EOF (-1); - 作用:
getc()、fscanf()等函数在"读取到文件末尾"或"读取错误"时,会返回EOF,告诉程序"停止读取"; - 误区:文件的最后不会存储"EOF字符",EOF是函数检测到"没有更多数据"后返回的标识。
生活类比:
EOF就像一本书的"最后一页"------你翻到最后一页,发现没有更多内容了,就知道"读完了"。书里不会写"结束"两个字,而是通过"没有更多页码"来判断。
4.2 如何正确判断文件结尾?
错误做法:用feof()判断循环条件
c
// 错误示例:先读再判断feof(),会导致最后一个字符重复读取
int ch;
while (!feof(fp)) {
ch = getc(fp);
putchar(ch); // 最后一次ch=EOF,会打印乱码(如■)
}
原因 :feof()只有在"读取到EOF之后"才会返回非零值,第一次读取到文件末尾时,feof()还是0,会进入循环再读一次,此时getc()返回EOF,导致错误。
正确做法:用函数返回值判断EOF
c
// 正确示例:先读取,再判断是否为EOF
int ch;
while ((ch = getc(fp)) != EOF) {
putchar(ch); // 只处理有效字符,不会读EOF
}
逻辑 :每次循环先调用getc()读取字符,若返回EOF(文件结尾/错误),则退出循环;否则处理字符,确保只处理有效数据。
4.3 区分"文件结尾"和"读取错误"
getc()返回EOF时,有两种可能:① 正常读取到文件结尾;② 读取过程中发生错误(如文件损坏、权限变更)。如何区分?用feof()和ferror()函数!
| 函数 | 原型 | 作用 | 返回值 |
|---|---|---|---|
| feof() | int feof(FILE *stream) |
判断是否读取到文件结尾 | 是→非零值,否→0 |
| ferror() | int ferror(FILE *stream) |
判断是否发生读取错误 | 是→非零值,否→0 |
实战:正确处理EOF和错误
c
#include #include int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "❌ 用法:%s >\n", argv[0]);
exit(1);
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "❌ 打开失败!\n");
exit(1);
}
int ch;
while ((ch = getc(fp)) != EOF) {
putchar(ch);
}
// 循环结束后,判断是文件结尾还是错误
if (feof(fp)) {
printf("\n✅ 正常读取到文件结尾!\n");
} else if (ferror(fp)) {
fprintf(stderr, "❌ 读取文件时发生错误!\n");
}
fclose(fp);
fp = NULL;
return 0;
}
4.4 避坑指南
- ❌ 用
feof()作为循环条件:导致最后一次读取EOF并处理,输出乱码; - ❌ 认为文件中存在EOF字符:试图在文件末尾手动添加"EOF",导致文件损坏;
- ✅ 用
(ch = getc(fp)) != EOF作为循环条件:先读再判断,避免无效读取; - ✅ 循环结束后检查
feof()和ferror():区分正常结尾和错误,提升程序健壮性。
五、fclose()函数------ 关闭文件的"收尾工作" 🚪
很多新手认为"程序结束后文件会自动关闭",从而忽略fclose()------这是一个致命错误!fclose()的核心作用是"刷新缓冲区+释放资源",不调用会导致数据丢失、资源泄漏。
5.1 函数原型与核心作用
c
int fclose(FILE *stream);
- 作用 :
- 刷新文件缓冲区:将缓冲区中未写入文件的数据(标准I/O默认缓冲)一次性写入文件;
- 释放文件资源:释放系统为文件分配的文件描述符、内存等资源;
- 返回值 :成功返回
0,失败返回EOF(如文件已关闭、stream为NULL)。
为什么必须调用fclose()?
标准I/O默认使用"全缓冲"(磁盘文件)或"行缓冲"(stdin/stdout)------数据写入文件时,先存到内存缓冲区,缓冲区满了才会写入磁盘。如果不调用fclose(),程序异常退出时,缓冲区中的数据会丢失!
生活类比:
fclose()就像"关水龙头"------你用水后如果不关水龙头,水会一直流(资源浪费);程序写文件后不调用fclose(),缓冲区的数据没写入磁盘(数据丢失),系统资源也一直被占用。
5.2 实战:正确关闭文件+错误处理
c
#include >
#include >
int main(void) {
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) {
fprintf(stderr, "❌ 打开失败!\n");
exit(1);
}
// 写入数据(此时数据在缓冲区,未写入磁盘)
fprintf(fp, "Hello, fclose()!");
// 关闭文件并检查是否成功
int ret = fclose(fp);
if (ret == EOF) {
fprintf(stderr, "❌ 关闭文件失败!\n");
exit(1);
}
fp = NULL; // 指针置空,避免野指针
printf("✅ 文件关闭成功!数据已写入磁盘~\n");
return 0;
}
5.3 特殊场景:缓冲区强制刷新(fflush())
如果需要"不关闭文件,立即将缓冲区数据写入磁盘"(如记录日志),可以用fflush()函数:
c
// 函数原型:int fflush(FILE *stream);
fprintf(fp, "紧急日志:程序运行异常!");
fflush(fp); // 强制刷新缓冲区,数据立即写入文件
5.4 避坑红黑榜
| 红榜(正确做法) | 黑榜(错误做法) | 后果 |
|---|---|---|
| 打开文件后,操作完成立即关闭 | 打开多个文件不关闭 | 系统文件描述符耗尽,无法打开新文件 |
| 关闭后将指针置空(fp=NULL) | 关闭后继续使用fp | fp变成野指针,操作导致程序崩溃 |
| 检查fclose()的返回值 | 忽略fclose()的返回值 | 关闭失败(如磁盘满)时无法发现 |
| 紧急数据用fflush()刷新 | 依赖程序退出自动刷新 | 程序异常退出时,缓冲区数据丢失 |
| 多个文件打开时,按"后开先关"顺序关闭 | 随意关闭文件 | 导致资源释放混乱,潜在错误 |
六、指向标准文件的指针------ 程序的"默认通信通道" 📞
C语言程序启动时,会自动打开3个标准文件 ,并提供预定义的FILE*指针,无需手动fopen()------它们是程序与外界(键盘、屏幕)通信的默认通道。
6.1 3个标准文件指针的核心信息
| 指针名 | 对应设备 | 类型 | 缓冲机制 | 常用操作函数 |
|---|---|---|---|---|
stdin |
键盘(标准输入) | 输入流 | 行缓冲(输入换行符/缓冲区满时刷新) | scanf()、getchar()、fgets(stdin) |
stdout |
显示器(标准输出) | 输出流 | 行缓冲(输出换行符/缓冲区满时刷新) | printf()、puts()、fputs(str, stdout) |
stderr |
显示器(标准错误) | 错误流 | 无缓冲(立即输出) | fprintf(stderr, "错误信息") |
核心特点:
- 程序启动即存在,退出时自动关闭,无需手动
fopen()/fclose(); stdout和stderr都输出到显示器,但stdout是行缓冲(遇到\n才刷新),stderr是无缓冲(立即输出);- 支持重定向:通过命令行或代码,将
stdin重定向到文件(从文件读输入),stdout/stderr重定向到文件(输出到文件)。
6.2 实战1:理解stdout和stderr的缓冲差异
c
#include .h>
#include .h>
int main(void) {
// stdout:行缓冲,未遇到\n,数据存在缓冲区
printf("这是stdout输出(行缓冲)");
// stderr:无缓冲,立即输出
fprintf(stderr, "\n这是stderr输出(无缓冲)\n");
// 程序退出前,stdout缓冲区会刷新,所以最终能看到stdout内容
return 0;
}
运行结果:
这是stderr输出(无缓冲)
这是stdout输出(行缓冲)
原因 :stderr无缓冲,立即输出;stdout行缓冲,未遇到\n,直到程序退出才刷新缓冲区。
6.3 实战2:标准文件重定向(命令行)
场景1:将stdout输出到文件(屏幕不显示,写入文件)
bash
# Windows/Linux通用:将程序输出写入output.txt
./program.exe > output.txt
场景2:将stdin从文件读取(不读键盘,读文件)
bash
# 程序从input.txt读取输入,输出到屏幕
./program.exe .txt
场景3:stdout输出到文件,stderr输出到屏幕(分离正常信息和错误)
bash
# Linux:stdout重定向到file.txt,stderr保持默认(屏幕)
./program > file.txt 2>&1
6.4 实战3:用标准指针操作文件
c
#include #include int main(void) {
char buffer[100];
// 从stdin(键盘)读取输入
printf("请输入一句话:");
fgets(buffer, sizeof(buffer), stdin); // 等价于gets(buffer),但更安全
// 向stdout(屏幕)输出
fprintf(stdout, "你输入的是:%s", buffer);
// 向stderr(屏幕)输出错误信息(示例)
fprintf(stderr, "⚠️ 这是一条错误提示(stderr)\n");
return 0;
}
6.5 避坑指南
- ❌ 手动关闭标准指针:
fclose(stdin),导致scanf()、getchar()无法使用; - ❌ 用
printf()输出错误信息:错误信息会被stdout缓冲,可能被重定向掩盖,应使用fprintf(stderr, ...); - ❌ 认为
stdout和stderr完全一样:两者缓冲机制不同,错误信息必须用stderr输出; - ✅ 重定向时分离stdout和stderr:避免错误信息被正常输出覆盖;
- ✅ 用
fgets(stdin, size, buffer)替代gets():避免缓冲区溢出,更安全。
🚨 新手全网高频踩坑总清单(背下来少走弯路)
- 不检查命令行参数
argc,直接用argv[1],参数不足时程序崩溃; fopen()打开文件后不检查fp == NULL,文件不存在时操作野指针;- 用文本模式(
"r"/"w")打开二进制文件,导致数据格式转换、文件损坏; - 用
char接收getc()返回值,无法识别EOF,导致无限循环; - 用
feof()作为循环条件,导致最后一次读取EOF并输出乱码; - 打开文件后不调用
fclose(),导致缓冲区数据丢失、资源泄漏; - 关闭文件后继续使用
fp,野指针导致程序崩溃; - 用
printf()输出错误信息,被stdout缓冲掩盖,无法及时发现错误; - 路径中Windows用单反斜杠
\,编译器解析为转义字符(如\t),路径错误; fread()/fwrite()参数写反(size和nmemb),读写数据量错误。
🎯 课后实战练习(动手=学会)
- 基础题:写一个程序,通过命令行参数接收文件名,统计文件中字母
'a'(不区分大小写)出现的次数; - 进阶题:用
getc()和putc()实现"文件加密"------将文件中每个字符的ASCII码+1(如'a'→'b'),输出到新文件; - 综合题:写一个命令行工具,支持"读取文件→替换指定字符→写入新文件",用法:
./replace 源文件 目标文件 旧字符 新字符; - 挑战题:将程序的正常输出(stdout)重定向到
log.txt,错误输出(stderr)重定向到error.txt,实现日志和错误分离。
📝 本章总结
- 命令行参数
argc/argv是程序的"外部指令接口",使用前必须检查参数个数,避免崩溃; fopen()是文件操作的"入口",必须指定正确的打开模式(文本/二进制),并检查返回值NULL;getc()/putc()是字符级读写的基础,支持所有文件类型,返回值必须用int接收,避免漏判EOF;EOF是"状态标识"而非文件字符,循环条件用(ch = getc(fp)) != EOF,循环结束后用feof()/ferror()区分结尾和错误;fclose()是"收尾工作",必须调用,否则数据丢失、资源泄漏,关闭后指针置空避免野指针;- 3个标准文件指针(
stdin/stdout/stderr)是默认通信通道,stderr无缓冲,错误信息优先用它输出。
标准I/O的核心是"细节+健壮性"------每个函数调用后检查返回值,正确处理错误和边界情况(如文件不存在、参数不足、读取到结尾),就能写出稳定可靠的文件操作程序。
🔥 本文由 BackCatK Chen(厦门市电子工程中级工程师) 全网最细保姆级C语言标准I/O教程
👍 觉得有用记得点赞、收藏、关注
#C语言 #C语言入门 #标准I/O #文件操作 #fopen #getc #putc #EOF #保姆级教程
🎁欢迎关注,获取更多技术干货!
🚀 C语言宝藏资源包免费送!14 本 C++ 经典书 + 编译工具全家桶 + 高效编程技巧,搭配 C 语言精选书籍、20 + 算法源码 + 项目规范,还有 C51 单片机 400 例实战!从零基础到嵌入式开发全覆盖,学生党、职场人直接抄作业~ 关注文章末尾的博客同名公众号,回复【C 语言】一键解锁全部资源,手慢也有!