初出茅庐的小李博客之C语言文件操作

news2025/1/18 4:38:23

C语言文件操作

在C语言中,文件操作主要是通过标准库函数来实现的。

今天有时间就来学习下一些常用的文件操作函数:

C 语言提供了一个 FILE 数据结构,记录了操作一个文件所需要的信息。该结构定义在头文件stdio.h,所有文件操作函数都要通过这个数据结构,获取文件信息。

struct _iobuf 
{
    char *_ptr;      // 指向缓冲区当前位置的指针
    int _cnt;        // 缓冲区中剩余的字节数
    char *_base;     // 指向缓冲区起始位置的指针
    int _flag;       // 文件状态标志(如错误、文件结束等)
    int _file;       // 文件描述符或句柄
    int _charbuf;    // 用于单字符缓冲
    int _bufsiz;     // 缓冲区大小
    char *_tmpfname; // 临时文件名指针(如果有)
};
typedef struct _iobuf FILE;  // 将结构体重命名为 FILE 类型

什么是文件指针:

开始操作一个文件之前,就要定义一个指向该文件的 FILE 指针,相当于获取一块内存区域,用来保存文件信息。

定义方式:

FILE* fp;

fopen()函数用来打开文件。所有文件操作的第一步,都是使用fopen()打开指定文件。这个函数的原型定义在头文件stdio.h

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

它接受两个参数。第一个参数是文件名(可以包含路径),第二个参数是模式字符串,指定对文件执行的操作,比如下面的例子中,r表示以读取模式打开文件;

第一次运行如果没有这个文件,程序会提示错误。如下所示,所以要想以只读的形式打开这个文件那么这样文件要事先存在。我在桌面手动创建了这个文件。再次试验就可以成果打开。

第一次打开出错:
在这里插入图片描述

第二次打开正常:
在这里插入图片描述

打开文件之后我们试着用fread()来读取文件信息。

fread()函数用于一次性从文件读取较大的数据块,主要用途是将文件内容读入一个数组,适合读取二进制数据。它的原型定义在头文件stdio.h

size_t fread(void* ptr, size_t size,size_t nmemb,FILE* fp);

它接受四个参数

  • ptr:数组地址。
  • size:每个数组成员的大小,单位为字节。
  • nmemb:数组的成员数量。
  • fp:文件指针。

读取字节数可以用一个变量来接收,

// 从文件中读取数据
BytesRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, fp);
printf("读到字节数BytesRead = %d\r\n",BytesRead);

在这里插入图片描述

读取数据时候有可能遇到文件为空的情况,这时候就需要检查是不是文件末尾。检查是否到文件末尾函数是feof

feof 是 C 标准库中的一个函数,用于检查文件是否已到达文件末尾(EOF,End of File)。它通常与文件读写函数(如 freadfgets 等)一起使用,以便在读取文件时检测到文件末尾。

feof 函数原型

int feof(FILE *stream);

参数解释

  • stream:指向 FILE 结构的文件指针。

返回值

  • 如果文件指针已到达文件末尾,则返回非零值 (真)。
  • 否则,返回零 (假)。

如果文本文件里面的内容是空的、那么读取到的数据字节数据应该是0。如图所示。

在这里插入图片描述

现在我试着网文件里写入一些信息。再尝试去读取信息

写入的信息是

This is a test txt.
Hello world!
end

编写读取数据到buffer的代码

    BytesRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, fp);
    printf("读到字节数BytesRead = %d\r\n",BytesRead);
    if (BytesRead == 0)
     {
        if (feof(fp))//文件到达末尾返回非零的真值 
        {
            printf("空文件、到达文件末尾\n");
        }
        else if (ferror(fp))
        {
            perror("没读到数据、读取文件时出错");
        }
        fclose(fp);
        return -1;
    }
    buffer[BytesRead] = '\0';
    printf("文件内容: %s\n", buffer);

读取信息入下所示:

打开文件时正常: No error
读到字节数BytesRead = 36
文件内容:
This is a test txt.
Hello world!
end
--------------------------------
Process exited after 0.04219 seconds with return value 0
请按任意键继续. . .

在这里插入图片描述

fclose 是 C 标准库中的一个函数,用于关闭已经打开的文件。关闭文件可以释放与该文件相关的资源,并确保所有缓冲区中的数据被写入文件。

fclose 函数原型

int fclose(FILE *stream);

参数解释

  • stream:指向 FILE 结构的文件指针,该文件指针指向要关闭的文件。

返回值

  • 如果成功关闭文件,返回0。
  • 如果发生错误,返回 EOF(通常为 -1)

完整的代码如下:

#include <stdio.h>

int main(void)
{
    FILE *fp;         // 定义一个 FILE 类型的指针
    char buffer[256]; // 定义一个缓冲区用于存储读取的数据
    size_t BytesRead; // 定义读取到多少个字节

    // 打开一个文件用于读取
    fp = fopen("example.txt", "r");
    if (fp == NULL)
    {
        perror("打开文件时出错");
        return -1;
    }
    else
    {
        printf("打开文件正常\r\n");
    }

    // 从文件中读取数据
    BytesRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, fp);
    printf("读到字节数 BytesRead = %zu\r\n", BytesRead);

    if (BytesRead == 0)
    {
        if (feof(fp)) // 文件到达末尾返回非零的真值
        {
            printf("空文件或到达文件末尾\r\n");
        }
        else if (ferror(fp))
        {
            perror("没读到数据,读取文件时出错");
        }
        fclose(fp);
        return -1;
    }

    // 为缓冲区添加字符串结束符
    buffer[BytesRead] = '\0';
    printf("文件内容:\r\n%s\r\n", buffer);

    // 关闭文件
    if (fclose(fp) == 0) // fclose 关闭成功返回0,关闭失败返回EOF
    {
        printf("成功关闭文件\r\n");
    }
    else
    {
        perror("关闭文件时出错");
    }

    return 0;
}

补充说明:EOF

C 语言的文件操作函数的设计是,如果遇到文件结尾,就返回一个特殊值。程序接收到这个特殊值,就知道已经到达文件结尾了。

头文件stdio.h为这个特殊值定义了一个宏EOF(end of file 的缩写),它的值一般是-1。这是因为从文件读取的二进制值,不管作为无符号数字解释,还是作为 ASCII 码解释,都不可能是负值,所以可以很安全地返回-1,不会跟文件本身的数据相冲突。

需要注意的是,不像字符串结尾真的存储了\0这个值,EOF并不存储在文件结尾,文件中并不存在这个值,完全是文件操作函数发现到达了文件结尾,而返回这个值。

fopen打开文件模式可能情况

以下是 fopen 函数的所有可能模式及其详细解释,包括注意事项:

模式模式说明文件指针位置文件存在文件不存在读操作写操作注意事项
r读模式文件开始读取文件返回 NULL允许不允许文件必须存在,否则返回 NULL。
w写模式文件开始文件内容被清空创建新文件不允许允许打开时会清空文件内容。
a追加写模式文件末尾文件末尾追加创建新文件不允许允许写操作总是在文件末尾。
r+读写模式文件开始读取和写入返回 NULL允许允许文件必须存在,否则返回 NULL。
w+读写模式文件开始文件内容被清空创建新文件允许允许打开时会清空文件内容。
a+读写模式文件末尾读取和追加创建新文件允许允许写操作总是在文件末尾。

注意事项

  1. r 模式

    • 只读模式,如果文件不存在,返回 NULL。因此在打开文件后,必须检查文件指针是否为 NULL
  2. w 模式

    • 只写模式,打开文件时会清空文件内容。如果文件不存在,则创建新文件。这种模式不允许读取文件内容。
  3. a 模式

    • 追加写模式,文件指针总是指向文件末尾。即使使用 fseek 移动文件指针,写入操作仍会在文件末尾。如果文件不存在,则创建新文件。这种模式不允许读取文件内容。
  4. r+ 模式

    • 读写模式,文件指针指向文件开始,允许读取和写入。如果文件不存在,返回 NULL。因此在打开文件后,必须检查文件指针是否为 NULL
  5. w+ 模式

    • 读写模式,打开文件时会清空文件内容,文件指针指向文件开始。如果文件不存在,则创建新文件。这种模式允许读取和写入,但注意文件内容会被清空。
  6. a+ 模式

    • 读写模式,文件指针指向文件末尾,允许读取和追加。如果文件不存在,则创建新文件。尽管可以读取文件内容,但写操作总是在文件末尾。

示例代码

以下是如何使用这些模式打开文件的示例代码:

#include <stdio.h>

void open_file(const char *filename, const char *mode) 
{
    FILE *fp = fopen(filename, mode);
    if (fp == NULL) 
    {
        perror("打开文件失败");
        return;
    }
    printf("以模式 '%s' 成功打开文件\r\n", mode);
    // 关闭文件
    if (fclose(fp) == 0) // fclose 关闭成功返回0,关闭失败返回EOF
    {
        printf("成功关闭文件\r\n");
    }
    else
    {
        perror("关闭文件时出错");
    }
}

int main(void) 
{
    open_file("example_r.txt", "r");
    open_file("example_w.txt", "w");
    open_file("example_a.txt", "a");
    open_file("example_r+.txt", "r+");
    open_file("example_w+.txt", "w+");
    open_file("example_a+.txt", "a+");
    return 0;
}

上边代码运行后只会产生四个文件

在这里插入图片描述

在这里插入图片描述

有关文件操作的接口还有以下几个,如果大家感兴趣可以点个在看,我继续更新!

fwrite():写入文件

fseek():移动文件指针到指定位置

ftell():获取文件指针当前位置

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

fputc():写入一个字符到文件中

fscanf():从文件中读取格式化输入

fprintf():按格式写入到文件中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1894943.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Blender渲染慢?那是你还不知道这5个技巧

Blender是一款功能强大且用途广泛的软件&#xff0c;可帮助 3D 艺术家和动画师创作出色的视觉内容。如果您使用过 Blender&#xff0c;您就会知道渲染可能非常耗时。渲染时间过长可能会令人烦恼并限制创造力。 在这篇文章中&#xff0c;我们将提供一些专家提示和想法以加快 Bl…

Elasticsearch:Painless scripting 语言(二)

这是继上一篇文章 “Elasticsearch&#xff1a;Painless scripting 语言&#xff08;一&#xff09;” 的续篇。 使用 field API 访问文档中的字段 警告&#xff1a;Field API 仍在开发中&#xff0c;应视为测试版功能。API 可能会发生变化&#xff0c;此迭代可能不是最终状态。…

用Vue3和Plotly.js绘制交互式3D烛形图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Plotly.js实现交互式K线图 应用场景 K线图广泛应用于金融领域&#xff0c;用于展示股票、外汇等金融产品的价格走势。它直观地呈现了开盘价、收盘价、最高价和最低价等信息&#xff0c;帮助投资者分析市场趋势…

Codeforces Round 955 (Div. 2, with prizes from NEAR!)(A~C题解)

这场比赛怎么说呢&#xff0c;一开始打的还算好&#xff0c;能进前1000&#xff0c;但是后面就被卡住了&#xff0c;这个确实没办法水平还是不够&#xff0c;学过的还是没想起来&#xff0c;后面继续练 A. Soccer 题解&#xff1a;水题一个&#xff0c;想要在过程中出现平局的…

1.HI3559AV100 官方开发板sample运行

1.内核、文件系统部分 有关uboot&#xff0c;kernel&#xff0c;rootfs部分就不赘述&#xff0c;直接在SDK提供的镜像文件进行烧录即可。2.编译MPP下的sample运行 实验前准备&#xff1a;通过NFS方式挂载到开发板与主机通信传输文件 驱动和库的部署&#xff1a;把MPP目录下的…

windows搭建mqtt服务器,并配置DTU收集传感器数据

1.下载并安装emqx服务器 参考&#xff1a;Windows系统下本地MQTT服务器搭建&#xff08;保姆级教程&#xff09;_mqtt windows-CSDN博客 这里我下载的是emqx-5.3.0-windows-amd64.zip版本 下载好之后&#xff0c;放到服务器的路径&#xff0c;我这里放的地方是&#xff1a;C…

day03-numpy数据类型

numpy数据类型 名称描述名称描述bool_布尔型数据类型&#xff08;True 或者 False&#xff09;float_float64 类型的简写int_默认的整数类型&#xff08;类似于 C 语言中的 long&#xff0c;int32 或 int64&#xff09;float16/32/64半精度浮点数:1 个符号位&#xff0c;5 个指…

Day64 代码随想录打卡|回溯算法篇---组合总和

题目&#xff08;leecode T39&#xff09;&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 …

Vulnhub靶场DC-5练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 利用burpsuite爆破文件包含的参数2. 文件包含3. nginx日志挂马4. 反弹shell5.漏洞利用和提权 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-5.zip 介绍&#xff1a; …

论文学习——基于类型检测的动态自适应多目标优化算法

论文题目&#xff1a;Dynamic adaptive multi-objective optimization algorithm based on type detection 基于类型检测的动态自适应多目标优化算法&#xff08;Xingjuan Cai a,b, Linjie Wu a,∗, Tianhao Zhao a, Di Wu c, Wensheng Zhang d, Jinjun Chen e&#xff09;Inf…

经典链表算法题:找到环的入口。清晰图示推导出来

Leetcode题目链接 原理 重画链表如下所示&#xff0c;线上有若干个节点。记蓝色慢指针为 slow&#xff0c;红色快指针为 fast。初始时 slow 和 fast 均在头节点处。 使 slow 和 fast 同时前进&#xff0c;fast 的速度是 slow 的两倍。当 slow 抵达环的入口处时&#xff0c;如…

doc文档下载

目录 下载 安装谷歌浏览器(chrome)Microsoft Edge浏览器 常见问题 下载 见邮件附件 安装 谷歌浏览器(chrome) 打开浏览器&#xff0c;地址栏输入&#xff1a;chrome://extensions/ 右上角打开开发者模式 点击如上图左上角的加载已解压的拓展程序&#xff0c;并选择刚刚解压…

【不锈钢酸退作业区退火炉用高温辐射计快速安装】

项目名称 不锈钢酸退作业区退火炉用高温辐射计快速安装 改造实施项目简介项目提出前状况:不锈钢生产过程中,各种型号的不锈钢带钢在退火工艺中对带钢温度的准确性要求很高,带钢温度的检测直接影响带钢的产品质量,不锈钢带钢温度测量依靠的是高温辐射计,其测量的准确性、稳…

YOLOv8入门 | 重要性能衡量指标、训练结果评价及分析及影响mAP的因素【发论文关注的指标】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

【Python画图-驯化seaborn】一文搞懂seaborn中的小提琴图实践、技巧、原理

【Python画图-驯化seaborn】一文搞懂seaborn中的小提琴图实践、技巧、原理 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容…

【信息学奥赛】CSP-J/S初赛06 算法基础及时间/空间复杂度等问题

本专栏👉CSP-J/S初赛内容主要讲解信息学奥赛的初赛内容,包含计算机基础、初赛常考的C++程序和算法以及数据结构,并收集了近年真题以作参考。 如果你想参加信息学奥赛,但之前没有太多C++基础,请点击👉专栏:C++语法入门,如果你C++语法基础已经炉火纯青,则可以进阶算法…

ScrollView组件No exact matches in call to initializer

在scrollview中使用text后报错&#xff0c;水平滚动使用的话&#xff0c;应该里面包含一个水平布局的组件&#xff0c;例如HStack组件&#xff0c;可以设置ScrollView滚动方向为 .horizontal或者 .vertical // 左右滑动ScrollView(.horizontal, showsIndicators: false) {HSt…

@amap/amap-jsapi-loader实现高德地图嵌入React项目中,并且做到点击地图任意一处,获得它的经纬度

1.第一步要加入项目package.json中或者直接yarn install它都可以 想必大家应该都会 "amap/amap-jsapi-loader": "0.0.7"2.加入项目中 关于接口获取key的接口 大家改成自己对应的项目请求方法 import React, { PureComponent } from react; import { Input…

MFC+MySQL应用:配置

MFCMySQL 1. MFC UI界面生成2. 数据库和表生成创建数据库创建表添加表数据 3. VS中配置MySQL环境 1. MFC UI界面生成 链接: MFC使用方法 可以根据用户自身需求生成单文档、对话框等不同样式的UI界面。 2. 数据库和表生成 可以在workbench或者MySQL Server中创建数据库和表。…

户用分布式光伏项目开发模式

随着全球对可再生能源的重视和技术的不断进步&#xff0c;分布式光伏发电作为一种清洁、高效、可再生的能源形式&#xff0c;正逐渐成为新能源发展的重要方向。户用分布式光伏项目&#xff0c;作为分布式光伏发电的重要组成部分&#xff0c;其开发模式对于推动光伏产业的普及与…