当前位置: 首页 > article >正文

C语言--文件操作教案

目录

教学目标

教学重点与难点

大纲: 

一、为什么使用文件?

二、文件的基本概念

三、二进制文件与文本文件

四、文件的打开与关闭

fopen()

fclose()

五、顺序读写操作

文本文件操作

二进制文件操作

六、随机读写操作

fseek():定位文件指针

ftell():获取当前位置偏移量

rewind():重置文件指针到文件开头

七、文件读取结束的判定

八、文件缓冲区

九、总结

十、练习设计


教学目标

  1. 理解文件存储的必要性及基本概念

  2. 掌握文件的打开、关闭和基本操作流程

  3. 熟练使用顺序读写与随机读写函数

  4. 理解文本文件与二进制文件的存储差异

  5. 掌握文件结束判定的正确方法

  6. 理解缓冲机制对文件操作的影响


教学重点与难点

重点

  • 文件打开模式("r"/"w"/"a"等)的选择与使用

  • 顺序读写函数(fgetc/fputcfgets/fputsfread/fwrite

  • 随机读写中的定位函数(fseekftellrewind

  • 文件结束判定的正确方法

难点

  • feof()的误用(常见错误点)

  • 二进制文件与文本文件的存储差异

  • 文件缓冲区对数据写入的影响


大纲: 

一、为什么使用文件?

讲解

  • 内存存储的局限性:程序运行时数据存储在内存中,程序退出后数据丢失。

  • 文件存储的优势:数据持久化,支持跨程序、跨设备的数据共享。

  • 应用场景:用户信息保存、日志记录、配置文件等。

互动提问

  • "如果一个计算器程序需要保存历史计算记录,如何实现?"


二、文件的基本概念

  1. 文件分类

    • 程序文件.c(源代码)、.obj(目标文件)、.exe(可执行文件)

    • 数据文件.txt(文本)、.bin(二进制)、.log(日志文件)

  2. 文件路径

    • 完整路径:如 C:\code\test.txt

    • 相对路径:相对于当前工作目录的路径(如 ../data/data.txt

示例

// 打开当前目录下的data.txt文件
FILE *fp = fopen("data.txt", "r");

三、二进制文件与文本文件

对比

特性

文本文件

二进制文件

存储方式

ASCII字符序列

原始二进制数据

空间效率

较低(如整数10000占5字节)

更高效(如整数占4字节)

处理速度

较慢(需字符处理)

更快(直接读写内存)

典型用途

文本数据(日志、配置)

图像、音频、结构化数据

代码示例

// 写入文本文件
FILE *text_fp = fopen("text.txt", "w");
fprintf(text_fp, "10000"); // 写入5个字符

// 写入二进制文件
FILE *bin_fp = fopen("data.bin", "wb");
int num = 10000;
fwrite(&num, sizeof(int), 1, bin_fp); // 写入4字节

四、文件的打开与关闭

fopen()
FILE *fopen(const char *filename, const char *mode);

模式参数

  • "r":只读; "w":只写(覆盖); "a":追加

  • "rb"/"wb":二进制模式

  • 返回值:成功返回文件指针,失败返回NULL
fclose()
int fclose(FILE *stream);
  • 关闭文件并释放资源,返回0表示成功。

代码示例

FILE *fp = fopen("data.txt", "w");
if (fp == NULL) {
    perror("Failed to open file");
    exit(EXIT_FAILURE);
}
fclose(fp);

五、顺序读写操作

文本文件操作

函数

功能

参数示例

fgetc()

读取单个字符

char ch = fgetc(fp);

fputc()

写入单个字符

fputc('A', fp);

fgets()

读取一行文本

fgets(buffer, 100, fp);

fputs()

写入字符串

fputs("Hello", fp);

二进制文件操作

函数

功能

参数示例

fread()

读取二进制数据

fread(buffer, size, count, fp);

fwrite()

写入二进制数据

fwrite(data, sizeof(int), 1, fp);

练习

  • 编写程序将文本文件复制为二进制文件。


六、随机读写操作

fseek():定位文件指针
int fseek(FILE *stream, long offset, int whence);
  • SEEK_SET:从文件开头开始

  • SEEK_CUR:从当前位置开始

ftell():获取当前位置偏移量
long ftell(FILE *stream);  
  • 返回从文件开头到当前位置的字节数,可用于计算文件大小或标记位置。
rewind():重置文件指针到文件开头
void rewind(FILE *stream);  
  • 示例:修改文件中间数据

    // 在二进制文件的第10个字节处写入字符'X'  
    FILE *fp = fopen("data.bin", "rb+");  // 需要读写权限  
    if (fp == NULL) {  
        perror("Failed to open file");  
        exit(EXIT_FAILURE);  
    }  
    // 移动到第10个字节的位置  
    fseek(fp, 10, SEEK_SET);  
    fputc('X', fp);  // 写入单个字符  
    fclose(fp);  
    

    互动提问

  • "如何快速获取文件的总大小?"
    fseek(fp, 0, SEEK_END);  
    long size = ftell(fp);  
    rewind(fp);  
    


七、文件读取结束的判定

常见误区:不要依赖feof()

  • 错误示例
    while (!feof(fp)) {  
        c = fgetc(fp);  
        // 处理字符  
    }  
    

    问题:当读取到文件末尾时,feof()会返回true,但此时已经读取了无效的EOF,导致循环多执行一次。

  • 正确方法

  • 文本文件

    • fgetc()返回EOF时结束:
      while ((c = fgetc(fp)) != EOF) {  
          // 处理字符  
      }  
      
    • fgets()返回NULL时结束:
      while (fgets(buffer, 100, fp) != NULL) {  
          // 处理行  
      }  
      
  • 二进制文件

    • fread()返回值小于预期读取的字节数时结束:
      size_t elements_read = fread(buffer, sizeof(int), 10, fp);  
      while (elements_read == 10) {  
          // 处理数据  
          elements_read = fread(buffer, sizeof(int), 10, fp);  
      }  
      
  • 练习

  • 编写一个程序,统计文本文件中的单词数量。


八、文件缓冲区

缓冲机制的作用

  • 写操作:数据先写入内存缓冲区,减少磁盘IO次数,提高效率。

  • 读操作:数据从磁盘一次性读入缓冲区,减少频繁访问磁盘的开销。

  • 关键函数

  • fflush():强制刷新缓冲区

    int fflush(FILE *stream);  
    
    • 用例:在程序崩溃前确保关键数据写入文件。

  • 关闭文件时自动刷新缓冲区

    fclose(fp); // 自动调用fflush(fp)  
    
  • 示例:缓冲区的影响

    FILE *fp = fopen("log.txt", "a");  
    fprintf(fp, "Start processing...\n");  // 数据暂存在缓冲区  
    // 程序突然崩溃,此时数据可能未写入文件!  
    fflush(fp); // 显式刷新,确保数据落地  
    

    互动讨论

  • "为什么在多线程程序中需要谨慎使用fflush()?"
    (提示:缓冲区竞争可能导致数据不一致)


九、总结

  • 核心流程
    打开文件(fopen)→ 读写操作 → 关闭文件(fclose)

  • 关键选择

    • 根据数据类型选择文本或二进制模式

    • 根据需求选择顺序或随机访问

  • 注意事项

    • 始终检查fopen()返回的文件指针是否为NULL

    • 避免依赖feof(),改用读取函数的返回值

    • 重要操作后调用fflush()确保数据持久化


十、练习设计

基础练习

  • 文本文件复制:编写程序将input.txt内容复制到output.txt

  • 二进制文件大小统计:编写程序输出文件的字节数。

  • 进阶练习

  • 日志文件处理:从日志文件中统计特定错误代码出现的次数。

  • 二进制数据修改:在二进制文件中查找并替换特定整数值。

  • 综合项目

  • 学生信息管理系统

    • 使用文本文件存储学生姓名、成绩。

    • 实现添加、查询、删除学生信息功能。

    • 用二进制文件优化存储效率。


  • 附录:常见错误与调试技巧

  • 文件路径错误:确保路径正确(绝对/相对路径)。

  • 模式不匹配:如用"r"模式打开不存在的文件会失败。

  • 缓冲区溢出fgets()的第二个参数要足够大。

  • 权限问题:检查文件是否可读写(如Windows的只读属性)。


http://www.kler.cn/a/612509.html

相关文章:

  • Mybatis缓存模块分析-源码
  • C# SerialPort 类中清空缓存区的方法
  • 如何使用腾讯云HAI快速、高质量生成Stable Diffusion图片
  • vmwaretools解压失败|vmware tools distrib cannot mkdir read only file system|bug汇总
  • 2025年渗透测试面试题总结-某奇安信-Ateam(题目+回答)
  • Oracle初识:登录方法、导入dmp文件
  • Qt弹出新窗口并关闭(一个按钮)
  • JVM 概述/结构/架构/生命周期
  • 短信验证码安全需求设计
  • C语言 【实现电脑关机小游戏】非常好玩
  • 【Zookeeper搭建】Zookeeper分布式集群搭建完整指南
  • git中feature跟hotfix是什么意思
  • Python定时任务的高效实现:精准触发mutoubar()方法
  • Golang Beego SQL链式查询(包含Join关联)
  • 使用 Docker 18 安装 Eureka:解决新版本 Docker 不支持的问题
  • 【漫话机器学习系列】159.单位阶跃激活函数(Unit-Step Activation Function)
  • UE学习记录part9
  • FALL靶场通关攻略
  • AutoDev 2.0 正式发布:智能体 x 开源生态,AI 自动开发新标杆
  • 如何快速对比两个不同的excel文件中的单元格的数据是否完全相同 并把不同的单元格的背景颜色更改为红色?