14.2【保姆级C语言入门】 标准I/O实战宝典:6大模块手把手教你搞定文件操作,新手直接上手!

✍️ 作者: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为例):
  1. 编译代码:gcc readfile.c -o readfile.exe

  2. 命令行输入:readfile.exe test.txt(test.txt是当前目录下的文件);

  3. 正确输出:

    复制代码
    ✅ 程序名:readfile.exe
    ✅ 待读取文件:test.txt
  4. 错误输入(参数不足):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;
}
常见错误原因及输出:
  1. 文件不存在:❌ 打开文件失败!原因:No such file or directory
  2. 权限不足(如Linux下文件为只读):❌ 打开文件失败!原因:Permission denied
  3. 路径错误(如"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 避坑指南

  1. ❌ 用char接收getc()返回值:ch = getc(fp)(char类型),无法识别EOF,导致无限循环;
  2. ❌ 拷贝二进制文件用文本模式:fopen(src, "r"),导致换行符转换,文件损坏(如图片、视频);
  3. ❌ 不检查putc()的返回值:写入失败(如磁盘满)时无法发现,导致拷贝不完整;
  4. ✅ 二进制文件用"rb"/"wb"模式:确保数据原样读写,兼容所有文件类型;
  5. ✅ 循环条件用(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 避坑指南

  1. ❌ 用feof()作为循环条件:导致最后一次读取EOF并处理,输出乱码;
  2. ❌ 认为文件中存在EOF字符:试图在文件末尾手动添加"EOF",导致文件损坏;
  3. ✅ 用(ch = getc(fp)) != EOF作为循环条件:先读再判断,避免无效读取;
  4. ✅ 循环结束后检查feof()ferror():区分正常结尾和错误,提升程序健壮性。

五、fclose()函数------ 关闭文件的"收尾工作" 🚪

很多新手认为"程序结束后文件会自动关闭",从而忽略fclose()------这是一个致命错误!fclose()的核心作用是"刷新缓冲区+释放资源",不调用会导致数据丢失、资源泄漏。

5.1 函数原型与核心作用

c 复制代码
int fclose(FILE *stream);
  • 作用
    1. 刷新文件缓冲区:将缓冲区中未写入文件的数据(标准I/O默认缓冲)一次性写入文件;
    2. 释放文件资源:释放系统为文件分配的文件描述符、内存等资源;
  • 返回值 :成功返回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()
  • stdoutstderr都输出到显示器,但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 避坑指南

  1. ❌ 手动关闭标准指针:fclose(stdin),导致scanf()getchar()无法使用;
  2. ❌ 用printf()输出错误信息:错误信息会被stdout缓冲,可能被重定向掩盖,应使用fprintf(stderr, ...)
  3. ❌ 认为stdoutstderr完全一样:两者缓冲机制不同,错误信息必须用stderr输出;
  4. ✅ 重定向时分离stdout和stderr:避免错误信息被正常输出覆盖;
  5. ✅ 用fgets(stdin, size, buffer)替代gets():避免缓冲区溢出,更安全。

🚨 新手全网高频踩坑总清单(背下来少走弯路)

  1. 不检查命令行参数argc,直接用argv[1],参数不足时程序崩溃;
  2. fopen()打开文件后不检查fp == NULL,文件不存在时操作野指针;
  3. 用文本模式("r"/"w")打开二进制文件,导致数据格式转换、文件损坏;
  4. char接收getc()返回值,无法识别EOF,导致无限循环;
  5. feof()作为循环条件,导致最后一次读取EOF并输出乱码;
  6. 打开文件后不调用fclose(),导致缓冲区数据丢失、资源泄漏;
  7. 关闭文件后继续使用fp,野指针导致程序崩溃;
  8. printf()输出错误信息,被stdout缓冲掩盖,无法及时发现错误;
  9. 路径中Windows用单反斜杠\,编译器解析为转义字符(如\t),路径错误;
  10. fread()/fwrite()参数写反(sizenmemb),读写数据量错误。

🎯 课后实战练习(动手=学会)

  1. 基础题:写一个程序,通过命令行参数接收文件名,统计文件中字母'a'(不区分大小写)出现的次数;
  2. 进阶题:用getc()putc()实现"文件加密"------将文件中每个字符的ASCII码+1(如'a'→'b'),输出到新文件;
  3. 综合题:写一个命令行工具,支持"读取文件→替换指定字符→写入新文件",用法:./replace 源文件 目标文件 旧字符 新字符
  4. 挑战题:将程序的正常输出(stdout)重定向到log.txt,错误输出(stderr)重定向到error.txt,实现日志和错误分离。

📝 本章总结

  1. 命令行参数argc/argv是程序的"外部指令接口",使用前必须检查参数个数,避免崩溃;
  2. fopen()是文件操作的"入口",必须指定正确的打开模式(文本/二进制),并检查返回值NULL
  3. getc()/putc()是字符级读写的基础,支持所有文件类型,返回值必须用int接收,避免漏判EOF
  4. EOF是"状态标识"而非文件字符,循环条件用(ch = getc(fp)) != EOF,循环结束后用feof()/ferror()区分结尾和错误;
  5. fclose()是"收尾工作",必须调用,否则数据丢失、资源泄漏,关闭后指针置空避免野指针;
  6. 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 语言】一键解锁全部资源,手慢也有!​

相关推荐
寻寻觅觅☆5 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
YJlio5 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
l1t5 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
赶路人儿6 小时前
Jsoniter(java版本)使用介绍
java·开发语言
ceclar1236 小时前
C++使用format
开发语言·c++·算法
码说AI7 小时前
python快速绘制走势图对比曲线
开发语言·python
Gofarlic_OMS7 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
星空下的月光影子7 小时前
易语言开发从入门到精通:补充篇·网络爬虫与自动化采集分析系统深度实战·HTTP/HTTPS请求·HTML/JSON解析·反爬策略·电商价格监控·新闻资讯采集
开发语言
老约家的可汗7 小时前
初识C++
开发语言·c++
wait_luky7 小时前
python作业3
开发语言·python