c语言文件操作(超详细)

前言

这次的博客,可以让大家快速掌握文件操作,方便大家快速找到不懂的内容

文件操作的作用以及基础

1. 为什么使用文件?

如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件

2. 什么是文件?

磁盘(硬盘)上的文件是文件。 但是在程序设计中,我们⼀般谈的⽂件有两种:程序文件、数据文件(从文件功能的角度来分类的)

3.文件名

⼀个文件要有⼀个唯⼀的文件标识,以便用户识别和引用  文件名包含3部分:文件路径+文件名主干+文件后缀 例如: c:\code\test.txt 为了方便起见,文件标识常被称为文件名

4.⼆进制文件和文本文件

根据数据的组织形式,数据文件被称为文本文件或者⼆进制文件。 数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的文件中,就是⼆进制文件 。如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

5.流

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出 操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流 想象成流淌着字符的河。 C程序针对文件、画面、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。

6.标准流

那为什么我们从键盘输入数据,向屏幕上输出数据,并没有打开流呢?

那是因为C语言程序在启动的时候,默认打开了3个流:

• stdin - 标准输入流,在大多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。 • stdout - 标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中

 • stderr - 标准错误流,大多数环境中输出到显示器界面。

这是默认打开了这三个流,我们使用scanf、printf等函数就可以直接进行输入输出操作的。 stdin、stdout、stderr 三个流的类型是: FILE * ,通常称为文件指针。 C语言中,就是通过 FILE* 的文件指针来维护流的各种操作的

7.文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。 每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE.

struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;
};
typedef struct _iobuf FILE;

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。 每当打开⼀个文件的时候,系统会根据文件的情况自动创建⼀个FILE结构的变量,并填充其中的信息,使用者不必关心细节。 ⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便

文件操作的使用

这里的讲解包括很多,慢慢来,前面的不懂没关系,我们直接看代码就好

文件的打开和关闭

我们使用fopen()函数打开 文件        使用fclose()关闭文件

再此之前可以看看他们的定义

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

int fclose( FILE *stream );

看看使用吧,

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

第一个参数是流,是一个文件指针 第二个参数是模式下面代码是"w"为只写模式

int main()
{FILE* pl= (FILE*)fopen("text.txt", "w");char a[20] = "hello world";char* p = a;while(*p!='\0')fputc(*p++,pl);fclose(pl);return 0;
}

在这里提醒一句,在只写模式中自能写入信息,不能读信息,待会还会在提醒,别急

看结果

绝对路径与相对路径

这个代码就是通过while循环,把一个字符串一个一个字符的存储在文件text.txt中

fopen的第一个参数为文件名其实在这里是相对路径,还可以使用绝对路径来作为参数

其实使用绝对路径更加严谨,因为相对路径是相对于本电脑而言的路径,绝对路径也不难,

可以从文件夹中复制出来,就拿刚刚生成的文件来试水

红方框所包的位置就是文件的绝对路径,其实很简单,找到文件,然后查看文件的属性

我们在把它写入代码中看看能否成功

但这里注意,位置给的是前面路径,最后还要加上自己的文件名

emmmm 失败了 为什么呢?

原因是转义字符,我们的 \t  \ddd 在这里d指的是数字呦 比如 \5 \6 \123 \24

这里是表示最少一位最多三位的8进制的数字

ok 我们现在在所有的转义字符中在多加入一个\就可以解决问题了

这样就成功了

文件的读写模式

我们就直接打出来把

其实这是由规律的,发现没

1 有后缀b就是二进制文件

2 r 读 w 写  a追加 记住就好 后缀+就是读写

3r只能读文件,一旦文件不存在 报错,但是w 和a可以创造文件 当它不存在时

4w(只写)每次打开文件时会把原文件的内容覆盖,然后重新写入

5 a追加 r 只读不会改变原有的文件,追加时是在原有的内容上追加的

最后大家要自行尝试各种模式下的文件操作

接下来要讲解一些相关的输入输出函数

函数名 功能 适用于
fgetc 字符输入函数 所有输入流
fputc 字符输出函数 所有输出流
fgets 文本行输入函数 所有输入流
fputs 文本行输出函数 所有输出流
fscanf 格式化输入函数 所有输入流
fprintf 格式化输出函数 所有输出流
fread ⼆进制输入 文件输入流
fwrite ⼆进制输出 文件输出

int fgetc(FILE *pf);
int fputc(int n,FILE *pf);
char*fgets(const char *a,size_t num,FILE *pf);
char *fputs(const char *a,FILE * pf);
int fread(cosnt char *buf,size_t typesize,size_t elementnums,FILE* pf);
int fwrite(const char *buf,size_t typesize,size_t elementnums,FILE* pf)

单个字符处理函数

fgetc 字符输入函数 所有输入流
fputc 字符输出函数 所有输出流

看代码

//fputc
int main()
{FILE* pf = fopen("BoKe.txt", "w");//1 fputc 针对文件流char a[20] = "djlkawj";char* p = "dkakdkla";for (int i = 0; i < strlen(a); i++){fputc(a[i], pf);}//2fputc 针对屏幕(标准输出流)while (*p != '\0'){fputc(*p++, stdout);}fclose(pf);
}

看结果

看fgetc

int main()
{FILE* pf = fopen("BoKe.txt", "r");int ch = 0;//注意要打括号,赋值操作符的优先级小于逻辑操作符//遍历文件流所有内容//针对文件流while((ch = fgetc(pf))&&ch!=EOF)putchar(ch);fclose(pf);printf("\n");int a = 0;//针对标准输入流while ((ch = fgetc(stdin))&&ch!= EOF){putchar(ch);}return 0;
}

行字符处理函数

char*fgets(const char *a,size_t num,FILE *pf);
char *fputs(const char *a,FILE * pf);

直接看代码

int main()
{//fputs 针对文件流FILE* pf = fopen("BoKe.txt", "w");char buffer[20] = "jdakldjad";fputs(buffer, pf);char buffer2[20] = "jdalkdajjadlk";fputs(buffer, pf);//针对 输出流fputs(buffer, stdout);fputs(buffer2, stdout);fclose(pf);//fgets 针对文件流pf = fopen("BoKe.txt", "r");char buffer3[20];fgets(buffer3, 10, pf);printf("%s\n", buffer3);//针对输出流char buffer4[20];fgets(buffer4, 10, stdin);printf("%s\n", buffer4);return 0;
}

看结果

值得注意的是在fgets中有一个限制大小的参数,该参数可以防止数组越界,并且注意的是在给数组值时该限制长度是字符串的长度

并且他不像gets puts一样可以自带换行,注意他不会自动换行

而且遇到换行不会结束,只有遇到\0或者文本结束符号ctrl+z才会结束

这个千万不要搞错了

格式化输入输出函数

fscanf 格式化输入函数 所有输入流
fprintf 格式化输出函数 所有输出流

int main()
{student s1 = { 20,"zhangsan",80 };FILE* pf = fopen("Test.txt", "w");fprintf(pf,"%d %s %d",s1.aag,s1.name,s1.score);fclose(pf);pf=fopen("Test.txt", "r");student s2 = { 0 };fscanf(pf, "%d %s %d", &(s2.aag), s2.name,&(s2.score));printf("%d %s %d\n", s2.aag, s2.name, s2.score);fclose(pf);pf=fopen("Test.txt", "wb");student arr[3] = { {20,"zhangsan",56},{25,"lisi",15},{65,"haha",99} };fwrite(arr, sizeof(student),3, pf);fclose(pf);return 0;
}

只针对文件流的输入输出

fread ⼆进制输入 文件输入流
fwrite ⼆进制输出 文件输出

我们仍然看上面的代码

此时文件中存储了,

student arr[3] = { {20,"zhangsan",56},{25,"lisi",15},{65,"haha",99} };

三个结构体成员,我们要取得最后一个结构体元素的内容怎么办

通过一个fseek()找到最后一个结构体元素的位置,也就是文件指针

的指向位置,在通过fread读出该结构体

当然 fwrite的使用就更加简单了,先看fseek和fread的联动

int main()
{FILE *pf = fopen("Test.txt", "rb");student s3 = { 0 };fseek(pf, -(long)sizeof(student), SEEK_END);fread(&s3, sizeof(student), 1, pf);printf("%d %s %d\n", s3.aag, s3.name, s3.score);return 0;
}

这个代码就是可以取出元素

看看fwrite

#include <stdio.h>
int main()
{int a = 10000;FILE* pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//⼆进制的形式写到⽂件中fclose(pf);pf = NULL;return 0;
}

fread 和fwrite都一样

4个参数 第一个是要取或读的地址,第二个是类型所占的字节大小 第三个是文件流

而且必须是文件流

当然这里是一定是二进制的,fwrite 是把内容以二进制写入文件

fread是把内容读入一个被指向的地址中

总算结束了,希望有所帮助吧

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

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

相关文章

计算机笔记(3)续20个

41.WWW浏览器和Web服务器都遵循http协议 42.NTSC制式30帧/s 44.三种制式电视&#xff1a;NTSC&#xff0c;PAL&#xff0c;SECAM 45.IP&#xff0c;子网掩码白话文简述&#xff1a; A类地址&#xff1a;取值范围0-127&#xff08;四段数字&#xff08;127.0.0.0&#xff09…

第十三届蓝桥杯大赛软件赛省赛CC++大学B组

第十三届蓝桥杯大赛软件赛省赛CC 大学 B 组 文章目录 第十三届蓝桥杯大赛软件赛省赛CC 大学 B 组1、九进制转十进制2、顺子日期3、刷题统计4、修建灌木5、x进制减法6、统计子矩阵7、积木画8、扫雷9、李白打酒加强版10、砍竹子 1、九进制转十进制 计算器计算即可。2999292。 2、…

Spoon Taking Problem(c++题解)

题目描述 &#xfffd;N 人が円卓に座っており&#xff0c;各人は反時計回りに順に 1, …, &#xfffd;1, …, N と番号付けられています&#xff0e;各人はそれぞれ左右どちらか一方の利き手を持っています&#xff0e; 円卓上には 1, …, &#xfffd;1, …, N と番号付け…

开机自启动

对win10,给一种开机自启动的设置方法: 1. winr 打开 2. 输入shell:startup打开 开始\程序\启动 3. 把想要自启动的应用的快捷方式放在这里即可 亲测有用

2024年计算机学科夏令营预推免信息最全汇总(包括计算机本学科和交叉学科)

我在看到新的夏令营信息后会及时更新其中这个表格&#xff0c;表格已经存放在百度网盘中了&#xff0c;下面是一张截图&#xff1a; 下面是存放表格的百度网盘地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1damn4jnG8r-XPe0HhvBRbw?pwd9b0h 提取码&#xff1a;9…

【JavaWeb】百度地图API SDK导入

百度地图开放平台 | 百度地图API SDK | 地图开发 (baidu.com) 登录注册&#xff0c;创建应用&#xff0c;获取AK 地理编码 | 百度地图API SDK (baidu.com) 需要的接口一&#xff1a;获取店铺/用户 所在地址的经纬度坐标 轻量级路线规划 | 百度地图API SDK (baidu.com) 需要的…

MySQL-SQL编写练习:基本的SELECT语句

基本的SELECT语句 1. SQL的分类 DDL:数据定义语言。CREATE \ ALTER \ DROP \ RENAME \ TRUNCATEDML:数据操作语言。INSERT \ DELETE \ UPDATE \ SELECT &#xff08;重中之重&#xff09;DCL:数据控制语言。COMMIT \ ROLLBACK \ SAVEPOINT \ GRANT \ REVOKE 学习技巧&#xf…

【测试篇】测试用例

文章目录 前言具体设计测试用例等价类边界值场景设计法判定表&#xff08;因果图&#xff09;正交排列&#xff08;用的非常少&#xff09;错误猜测法 前言 什么是测试用例&#xff1f;&#xff1f; 测试用例是针对软件系统或应用程序的特定功能或场景编写的一组步骤&#xf…

后端返还二进制excl表格数据时候,如何实现在前端下载表格功能及出现表格打开失败的异常处理。

背景&#xff1a; 后端返还一个二进制流的excl表格数据&#xff0c;前端需要对其解析&#xff0c;然后可提供给客户进行下载。 思路&#xff1a;把二进制流数据转换给blob对象&#xff0c;然后利用a标签进行前端下载。 代码&#xff1a; 后端返还 类似如下的数据 前端代码…

电商技术揭秘六:前端技术与用户体验优化

文章目录 引言一、前端技术在电商中的重要性1.1 前端技术概述1.2 用户体验与前端技术的关系 二、响应式设计与移动优化2.1 响应式设计的原则2.2 移动设备优化策略2.3 响应式设计的工具和框架 三、交互设计与用户体验提升3.1 交互设计的重要性3.2 用户体验的量化与优化3.3 通过前…

AI绘画:使用Stable Diffusion ComfyUI进行换脸:IPAdapter FaceID全面教程

在数字艺术和媒体编辑领域&#xff0c;换脸技术已经成为一种流行且强大的工具。它允许创作者将一个人物的面部特征无缝地转移到另一个人物上&#xff0c;创造出令人信服的视觉作品。Stable Diffusion ComfyUI提供了一个高效的平台&#xff0c;让用户能够轻松地实现换脸。本文将…

JSON的定义和基本使用

1、JSON的特点: JSON是一种轻量级的数据交换格式&#xff0c;是由字符串化的键值对构成。基于网络的前后端通信&#xff0c;数据在服务端和客户端之间进行传输&#xff0c;采用的就是JSON的格式来进行交互。JSON采用完全独立于语言的文本格式&#xff0c;JSON的数据格式完全独…

OpenHarmony相机和媒体库-如何在ArkTS中调用相机拍照和录像。

介绍 此Demo展示如何在ArkTS中调用相机拍照和录像&#xff0c;以及如何使用媒体库接口进行媒体文件的增、删、改、查操作。 本示例用到了权限管理能力ohos.abilityAccessCtrl 相机模块能力接口ohos.multimedia.camera 图片处理接口ohos.multimedia.image 音视频相关媒体业…

了解以太坊虚拟机(EVM)

了解以太坊虚拟机&#xff08;EVM&#xff09; 以太坊虚拟机&#xff08;Ethereum Virtual Machine&#xff0c;简称EVM&#xff09;是以太坊网络的核心组件之一&#xff0c;它承担着智能合约执行的重要任务 特点 智能合约执行环境&#xff1a;EVM提供了一个安全的环境&#xf…

易宝OA ExecuteSqlForDataSet SQL注入漏洞复现

0x01 产品简介 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台,具有信息管理、 流程管理 、知识管理(档案和业务管理)、协同办公等多种功能。 0x02 漏洞概述 易宝OA ExecuteSqlForDataSet接口处存在SQL注入漏洞,未经身份认证的攻击者可以通过…

韩顺平Java | C24 MySQL数据库

MySQL安装和配置 MySQL5.7(稳定)、Navicat、SQLyog MySQL三层结构&#xff1a;数据库管理系统DBMS-数据库DB-表Table&#xff08;行/记录-用对象表示&#xff09; 使用命令行窗口连接MySQL数据库 net stop mysql服务名 net start mysql服务名 mysql -h 主机名 -P端口 -u用户…

k8s部署微服务例子

一、部署服务 需要部署minio、nacos、mysql、consul、elasticsearch、视频解析服务、nfs、skywalking-oap及ui。 二、三个微服务程序 minio服务解析视频-》上传到minio进行存储&#xff0c;构造领域对象信息保存到hive&#xff08;hive on spark&#xff09;异步处理-》元数据…

Acwing-石子合并

282. 石子合并 - AcWing题库 所需知识&#xff1a;区间dp 区间dp模板题。 区间dp常用模板&#xff1a; for (int len 1; len < n; len) { // 遍历区间的长度for (int i 1; i len - 1 < n; i) { // 枚举区间起点int j i len - 1; // 区间…

STM32-05基于HAL库(CubeMX+MDK+Proteus)串行通信案例(中断方式接收命令)

文章目录 一、功能需求分析二、Proteus绘制电路原理图三、STMCubeMX 配置引脚及模式&#xff0c;生成代码四、MDK打开生成项目&#xff0c;编写HAL库的功能代码五、运行仿真程序&#xff0c;调试代码 一、功能需求分析 在中断机制实现按键检测的案例之后&#xff0c;我们介绍串…

无问芯穹 MaaS AI 平台公测免费试用笔记:二

上一篇笔记中&#xff0c;聊过了无问芯穹的 MaaS 服务中的“虚拟机”产品。本篇文章来聊聊最近宣传中提到的大手笔免费百亿 Token 用量的“大模型服务平台” 吧。 分享下这个支持异构芯片推理的国产 “Replicate”、模型市场服务使用的经验和小技巧。 写在前面 本篇文章根据…