23. C语言 文件操作详解

ops/2025/1/24 16:59:01/

本章目录:

    • 前言
    • 文件操作概览
      • 1. 打开文件
        • `fopen()` 函数
        • 二进制文件模式
      • 2. 写入文件
        • `fputc()` 写单个字符
        • `fputs()` 写字符串
        • `fprintf()` 格式化输出
      • 3. 读取文件
        • `fgetc()` 读取单个字符
        • `fgets()` 读取一行
        • `fscanf()` 格式化读取
      • 4. 关闭文件
      • 5. 文件指针控制:`fseek()` 与 `ftell()`
        • `fseek()` 设置文件指针
        • `ftell()` 获取文件指针位置
      • 6. 二进制文件操作
        • `fread()` 读取二进制数据
        • `fwrite()` 写入二进制数据
      • 总结


前言

C 语言作为一种低级语言,提供了丰富的文件操作函数,允许程序员读取和写入文件,不论是文本文件还是二进制文件。理解这些操作对于处理持久化数据、进行文件管理等任务至关重要。在本篇博客中,我们将详细探讨 C 语言中的文件读写操作,带你了解如何创建、打开、读取、写入文件,以及如何使用文件指针在文件中进行精细化控制。


文件操作概览

在 C 语言中,文件的操作依赖于一组标准库函数。这些函数让我们可以打开文件、读取或写入数据、控制文件指针的位置,并最终关闭文件。具体的操作流程如下:

  1. 打开文件
  2. 读写文件
  3. 关闭文件
  4. 文件指针的操作

1. 打开文件

在 C 语言中,使用 fopen() 函数来打开一个文件。fopen() 可以打开一个已存在的文件,或创建一个新文件,具体取决于文件路径和操作模式。

fopen() 函数
FILE *fopen(const char *filename, const char *mode);
  • filename:要打开或创建的文件名。
  • mode:文件访问模式,决定了文件的读写方式。

常见的文件访问模式有:

模式描述
"r"只读模式,文件必须已存在。
"w"写入模式,若文件存在则清空,若文件不存在则创建。
"a"追加模式,若文件存在,则数据写入文件末尾;若文件不存在,则创建。
"r+"读写模式,文件必须已存在。
"w+"读写模式,若文件存在则清空,若文件不存在则创建。
"a+"读写模式,文件不存在则创建,写入数据追加到文件末尾。
二进制文件模式

除了上述的文本文件模式,处理二进制文件时需要使用不同的模式,如:

模式描述
"rb"打开一个已有的二进制文件,读取模式。
"wb"打开一个二进制文件进行写入,若文件不存在则创建。
"ab"打开二进制文件进行追加写入。
"rb+"打开二进制文件进行读写。

2. 写入文件

C 语言提供了多个函数来向文件中写入数据,下面我们介绍几种常用的写入方式。

fputc() 写单个字符

fputc() 函数用于向文件写入一个字符。

int fputc(int c, FILE *fp);
  • c:要写入的字符(以整数形式表示)。
  • fp:指向文件的文件指针。

示例:

FILE *fp = fopen("example.txt", "w");
fputc('A', fp);
fclose(fp);
fputs() 写字符串

fputs() 用于写入一个字符串,直到遇到 \0(字符串结束符)为止。

int fputs(const char *s, FILE *fp);
  • s:要写入的字符串。
  • fp:指向文件的文件指针。

示例:

FILE *fp = fopen("example.txt", "w");
fputs("Hello, World!\n", fp);
fclose(fp);
fprintf() 格式化输出

如果需要格式化数据输出到文件,可以使用 fprintf() 函数,它与 printf() 类似。

int fprintf(FILE *fp, const char *format, ...);

示例:

FILE *fp = fopen("example.txt", "w");
fprintf(fp, "Name: %s, Age: %d\n", "Alice", 30);
fclose(fp);

3. 读取文件

在 C 语言中,读取文件内容常用的函数有 fgetc()fgets()fscanf()

fgetc() 读取单个字符

fgetc() 从文件中读取一个字符。

int fgetc(FILE *fp);
  • fp:文件指针。
  • 返回值:读取的字符。如果读取失败,返回 EOF

示例:

FILE *fp = fopen("example.txt", "r");
char c = fgetc(fp);
printf("Read character: %c\n", c);
fclose(fp);
fgets() 读取一行

fgets() 用于从文件中读取一行,最多读取指定的字符数。

char *fgets(char *buf, int n, FILE *fp);
  • buf:保存读取内容的缓冲区。
  • n:要读取的最大字符数。
  • fp:文件指针。

示例:

FILE *fp = fopen("example.txt", "r");
char buffer[255];
fgets(buffer, sizeof(buffer), fp);
printf("Read line: %s", buffer);
fclose(fp);
fscanf() 格式化读取

fscanf() 类似于 scanf(),但它是从文件中读取数据。它会根据给定的格式进行读取。

int fscanf(FILE *fp, const char *format, ...);

示例:

FILE *fp = fopen("example.txt", "r");
char name[50];
int age;
fscanf(fp, "%s %d", name, &age);
printf("Name: %s, Age: %d\n", name, age);
fclose(fp);

4. 关闭文件

每次完成文件操作后,我们应该使用 fclose() 函数关闭文件,确保文件资源被正确释放。

int fclose(FILE *fp);
  • fp:要关闭的文件指针。
  • 返回值:如果成功关闭文件,返回 0;否则返回 EOF

示例:

FILE *fp = fopen("example.txt", "w");
fprintf(fp, "Some content\n");
fclose(fp);

5. 文件指针控制:fseek()ftell()

在实际应用中,我们经常需要在文件中移动文件指针来实现随机访问。C 语言通过 fseek()ftell() 提供了这种能力。

fseek() 设置文件指针

fseek() 用于设置文件指针的位置。它的原型如下:

int fseek(FILE *stream, long offset, int whence);
  • stream:文件指针。
  • offset:相对于 whence 的偏移量。
  • whence:基准位置,可以是 SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)。

示例:

FILE *fp = fopen("example.txt", "r+");
fseek(fp, 10, SEEK_SET);  // 将文件指针移到文件开头10个字节的位置
fputc('A', fp);           // 在该位置写入字符
fclose(fp);
ftell() 获取文件指针位置

ftell() 返回当前文件指针的位置。

long ftell(FILE *stream);

示例:

FILE *fp = fopen("example.txt", "r");
fseek(fp, 10, SEEK_SET);
long pos = ftell(fp);  // 获取当前文件指针的位置
printf("Current position: %ld\n", pos);
fclose(fp);

6. 二进制文件操作

对于二进制文件,我们通常使用 fread()fwrite() 函数来读取和写入数据。

fread() 读取二进制数据
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
  • ptr:指向存储读取数据的缓冲区。
  • size_of_elements:每个元素的字节大小。
  • number_of_elements:要读取的元素数量。
fwrite() 写入二进制数据
size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
  • ptr:指向要写入数据的缓冲区。
  • size_of_elements:每个元素的字节大小。
  • number_of_elements:要写入的元素数量。

总结

通过本篇博客的讲解,我们深入了解了 C 语言中的文件操作,包括文件的打开、读取、写入、关闭以及文件指针的管理。掌握这些基本的文件操作可以帮助我们在编写程序时处理文件数据,实现更复杂的功能。在实际应用中,文件操作常



http://www.ppmy.cn/ops/152788.html

相关文章

Sklearn机器学习第十五天|机器学习算法原理

第3章 机器学习算法原理 3.1 感知机算法 感知机算法:找到一条直线把二分类问题分开 3.1.1 决策函数 3.1.1.1 sign函数 3.1.2 损失函数 3.1.3 目标函数 3.1.4 目标函数优化算法 3.2 线性回归 3.2.1 决策函数 3.2.2 目标函数 3.2.3 目标函数优化问题 3.2 逻辑回归…

【C++图论 并集查找】2492. 两个城市间路径的最小分数|1679

本文涉及知识点 C图论 并集查找(并查集) LeetCode2492. 两个城市间路径的最小分数 给你一个正整数 n ,表示总共有 n 个城市,城市从 1 到 n 编号。给你一个二维数组 roads ,其中 roads[i] [ai, bi, distancei] 表示城市 ai 和 …

C++|开源日志库log4cpp和glog

文章目录 log4cpp 和 glog对比1. **功能对比**2. **易用性和配置**3. **性能**4. **线程安全**5. **日志输出**6. **功能扩展**7. **适用场景**8. **总结** 其它开源C日志库1. **spdlog**2. **easylogging**3. **Boost.Log**4. **loguru**5. **Poco Logging**6. **Qt Logging (…

蓝桥杯例题一

不管遇到多大的困难,我们都要坚持下去。每一次挫折都是我们成长的机会,每一次失败都是我们前进的动力。路漫漫其修远兮,吾将上下而求索。只有不断努力奋斗,才能追逐到自己的梦想。不要害怕失败,害怕的是不敢去尝试。只…

一文夯实垃圾收集的理论基础

如何判断一个引用是否存活 引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。 优点:可即刻回收垃圾&a…

【YOLOv11改进[Backbone]】使用LSKNet替换Backbone | 用于遥感目标检测的大型选择性核网络 | 2023

本文将进行在YOLOv11中使用LSKNet替换Backbone魔改v11的实践,文中含全部代码、详细修改方式。助您轻松理解改进的方法。 目录 一 LSKNet 二 魔改v11 1 整体修改 ① 添加python文件 ② 修改ultralytics/nn/tasks.py文件 2 配置文件

Alibaba Spring Cloud 四 Seata 的核心组件:TC

Seata 的 Transaction Coordinator (TC) 是分布式事务架构中的核心组件之一,它负责管理全局事务的生命周期,包括事务的创建、状态维护以及协调各分支事务的提交和回滚。以下是有关 TC 的详细解析及其配置和使用方法: 1. TC 的核心功能 全局事…

【Matlab高端绘图SCI绘图模板】第003期 绘制面积填充图

1.面积图简介 面积图和折线图一样,面积图也用于强调数量随时间而变化的程度,也可用于引起人们对总趋势的注意。他们最常用于表现趋势和关系,而不是传达特定的值。 所有的数据都从相同的零轴开始。每一个数据集的起点不同,都是基…