c语言 文件与文件操作

🏠 一.引言 

    我们日常生活中会将我们制作的ppt,word等存放在文件里进行归类,你是否知道我们能用cC语言对文件进行操作呢(比如文件的打开,关闭和读写等)?那接下来跟博主一起来学习下吧。

🏠二.什么是文件

   磁盘上的文件就是文件,可以理解为一个信息集合体。我们一般根据文件的功能将其分为两类:一类是程序文件,一类是数据文件。

  ◕‿◕文件名

 文件名相当于是一个标志,⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤。

⽂件名包含3部分: ⽂件路径+⽂件名主⼲+⽂件后缀 。 比如: c:\code\test.txt

小补充:1.文件名可以不包含后缀名,比如.txt文件类型,显示文件扩展名就可以看到

               2.文件名后缀表示文件的默认打开方式

               3.文件名有一些非法字符,如\ / : * ? " < > |

1.程序文件

      程序文件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows环境后缀为.exe)。

2.数据文件

   ⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。

 数据文件分类

数据文件按数据的组织形式,一般分为二进制文件和文本文件。数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存,就是⼆进制⽂件。如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂本⽂件。

🏠三.对文件的操作

    类比我们平时喝汽水我们常规步骤是打开瓶子,喝汽水,最后再关闭瓶子。类似地,我们对文件的操作首先是要打开文件,对文件进行输入或输出,最后再关闭文件。我们先来细🔒打开文件和关闭文件。

   在介绍打开与关闭文件之前,我们先来普及一个概念叫做流。

1.流

   流的源来:我们对一个文件可以将他输入屏幕/另一个文件等等不同的设备,这个时候不同设备对你的要求不同。好比一个工厂,我们需要多条生产线,一条分装这种产品,另一条分装那一种产品....我们的流就好比一条生产线分出的多个岔口这些岔口指向不同设备。

  C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的.⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。

1.1标准流

那为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢?那是因为C语⾔程序在启动的时候,默认打开了3个流:
stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。
stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出
流中。
stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。
这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。
更具体点,我们可以知道流被定义为指针( 更多地理解为在流中操作的工具),指针就是地址,我们可以通过地址(流)找到这个我们所要的设备。以上三种流都是 FILE*类型的指针, 通常称为 ⽂件指针 C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。

1.2文件指针

每个被使⽤的⽂件都在内存中开辟了⼀个相应的 ⽂件信息区 ,⽤来 存放⽂件的相关信息 (如⽂件的名 字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE.
struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;};
typedef struct _iobuf FILE;
每当打开⼀个⽂件的时候,系统会根据⽂件的情况⾃动创建⼀个FILE结构的变量,并填充其中的信
息, 一般是用一个FILE*指针来维护它的。 定义pf是⼀个 指向FILE类型数据的指针变量 。可以使pf指向某个⽂件的 ⽂件信息区 (是⼀个结构体变 量)。 通过该⽂件信息区中的信息就能够访问该⽂件。 也就是说,通过⽂件指针变量能够间接找到与 它关联的⽂件。

2.文件的打开与关闭

 基于之前的理解,我们是用一个文件指针来对文件进行间接维护和操作,所以我们可以推出FILE*类型指针是我们对文件进行读写等操作所必备的,因此我们就可以理解fopen的工作原理了

fopen  这是用来打开文件的函数原型如下

这下应该知道为什么会返回一个FILE*类型的指针了吧。
fclose 这个函数用来关闭文件
注意: 1.使用fopen如果文件打开失败,会返回个空指针,这时他就是一个空指针,我们需要检测             下。
            2.fclose能力是关闭文件,但不能置指针为空指针,我们应该手动置为空。
int main()
{FILE* pf=fopen("data.txt","w");if (pf == NULL){perror("fopen");return 1;}fclose(pf);pf = NULL;return 0;
}

文件打开后我们当然要用比如进行读写,fopen第二个参数就是打开方式

注意:对于一个没有存在的文件直接进行读会报错

3.文件的顺序读写

  

我们知道文件里内容是有光标的,顺序读写就指的是这个光标一直往后推进

一些顺序顺序读写函数

注意:fread和fwrite只适用于文件流

3.1fgetc和fputc

从函数名可以看出putc是放一个字符,getc是读一个字符

3.2 fgets和fputs函数

注意:fgets是从流中读取num-1个字符因为还要给\0留位

int main()
{FILE* pf = fopen("data2.txt", "r");if (pf == NULL){perror("fopen");return 1;}/*char arr[20] = "abcdef";fputs(arr, pf);*/char name[20] = "xxxxxxxxxxxx";fgets(name, 7, pf);printf("%s\n",name);fclose(pf);pf = NULL;return 0;
}

3.3 fscanf和fprintf函数

struct S
{char name[20];int age;float score;
};int main8()
{struct S s = { 0 };FILE* pf = fopen("dataa.txt", "r");//打开文件if (pf == NULL){perror("fopen");return 1;}//读文件  注意取址符&fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));//读pf中数据到结构体//写入fprintf(stdout, "%s %d %.1f\n", s.name, s.age, s.score);//将结构体写入到标准输出流//关闭文件fclose(pf);pf = NULL;return 0;
}

3.4 fwrite和fread

  这两个文字是针对二进制文件的,也就是他的读写都是针对二进制。

struct S
{char name[20];int age;float score;};
int main()
{struct S s = { "zhangsan",18,99.6 };FILE* pf = fopen("dataa1.txt", "wb");//二进制写入if (pf == NULL){perror("fopen");return 1;}fwrite(&s, sizeof(s), 1, pf);fclose(pf);pf = NULL;return 0;
}

4.文件的随机读写

我们前面知道顺序指的是光标,那我们能不能让光标随便动读写我们想要的呢?这时就要用到我们的随机读写函数。随机指的是你指哪打哪

4.1 fseek函数

fseek是根据根据⽂件指针的位置和偏移量来定位⽂件指针

4.2  ftell

ftell函数返回⽂件指针相对于起始位置的偏移量,以便我们进行调整

4.3 rewind

当我们不知道光标在哪想从头来过就可以用rewind让⽂件指针的位置回到⽂件的起始位置

int main2()
{FILE* pf = fopen("data2.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch = 0;ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);//fseek(pf, -3, SEEK_CUR);   从当前位置//fseek(pf, 3, SEEK_SET);    从开头fseek(pf, -4, SEEK_END);  // 从末尾ch = fgetc(pf);printf("%c\n", ch);long size = 0;size = ftell(pf);//返回现在光标距起始位置的偏移量printf("当前偏移量离起始位置为%ld\n", size);rewind(pf);//使光标回到开头ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}

🏠四.文件读取结束的判定

1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF fgetc ),或者 NULL fgets
例如:
fgetc 判断是否为 EOF .
fgets 判断返回值是否为 NULL .
2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数。
fread判断返回值是否⼩于实际要读的个数.
被错误使用的feof和ferror
1.   feof
牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。
feof 的作⽤是:当⽂件读取结束的时候, 判断是读取结束的原因是否是:遇到⽂件尾结束

2.ferror

他的作用是判断在文件读取结束后,是否因为遇到错误而结束

好了本次分享结束啦,喜欢的话给博主来个三连吧~๑ᵒᯅᵒ๑

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

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

相关文章

TCP/IP详解——FTP 协议,Telnet协议

文章目录 1. FTP 协议1.1 FTP的应用1.2 FTP传输文件的过程1.3 FTP传输模式1.4 主动模式&#xff08;Active Mode&#xff09;1.5 Active Mode 抓包分析1.6 被动模式&#xff08;Passive Mode&#xff09;1.7 Passive Mode 抓包分析 2. Telnet 协议2.1 Telnet 概念2.2 Telnet 协…

Python电能质量扰动信号分类(一)基于LSTM模型的一维信号分类

目录 引言 1 数据集制作与加载 1.1 导入数据 1.2 制作数据集 2 LSTM分类模型和超参数选取 2.1 定义LSTM分类模型 2.2 定义模型参数 3 LSTM模型训练与评估 3.1 模型训练 3.2 模型评估 往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承…

Word写大论文常见问题(持续更新)

脚注横线未定格 解决方案&#xff1a;“视图”-“草图”&#xff0c;“引用”-“显示备注”-选择“脚注分隔符”&#xff0c;把横线前的空格删掉。 2.PPT做的图插入word中清晰度太低 解决方案&#xff1a;PPT-图形-“另存为图片”-“可缩放矢量图格式”-粘贴到word中。

RDD编程

目录 一、RDD编程基础 &#xff08;一&#xff09;RDD创建 &#xff08;二&#xff09;RDD操作 1、转换操作 2、行动操作 3、惰性机制 &#xff08;三&#xff09;持久化 &#xff08;四&#xff09;分区 &#xff08;五&#xff09;一个综合实例 二、键值对RDD &am…

社交网络分析3:社交网络隐私攻击、保护的基本概念和方法 + 去匿名化技术 + 推理攻击技术 + k-匿名 + 基于聚类的隐私保护算法

社交网络分析3&#xff1a;社交网络隐私攻击、保护的基本概念和方法 去匿名化技术 推理攻击技术 k-匿名 基于聚类的隐私保护算法 写在最前面社交网络隐私泄露用户数据暴露的途径复杂行为的隐私风险技术发展带来的隐私挑战经济利益与数据售卖防范措施 社交网络 用户数据隐私…

[AI工具推荐]AiRestful智能API代码生成

智能API代码示例生成工具AiRestful 一、产品介绍二、如何使用1、第一步(必须):2、第二步(可选):3、第三步(智能生成): 三、如何集成到您的网站(应用)1、开始接入2、接入案例 四、注意点 一、产品介绍 AiRestful是一款基于智能AI的,帮助小白快速生成任意编程语言的API接口调用示…

Axure元件的介绍使用以及登录界面

一、Axure元件介绍 简介&#xff1a; Axure元件是一种功能强大的设计工具&#xff0c;专门用于用户体验设计和交互设计。它可以帮助设计师创建可交互的原型&#xff0c;并实现各种界面元素的设计和布局。 Axure元件的基本特点包括&#xff1a; 多样性&#xff1a;Axure元件包括…

【DataSophon】大数据服务组件之Flink升级

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

从 0 开始实现一个 SpringBoot + Vue 项目

从 0 开始实现一个 SpringBoot Vue 项目 从 0 开始实现一个 SpringBoot Vue 项目软件和工具创建 SpringBoot 后端项目创建 MySQL 数据库配置文件实现增删改查接口Model 层mapper 层service 层controller 层测试 从 0 开始实现一个 SpringBoot Vue 项目 软件和工具 后端开发…

一二三应用开发平台部署文档——开发环境搭建手册

背景 开源平台在ReadMe文档中简要描述了如何部署与启动以及重要注意事项&#xff0c;有小伙伴私信我希望提供一个详细具体的部署说明&#xff0c;然后联想到自己出于学习或研究目的&#xff0c;去搭建一些开源项目时&#xff0c;面对简要的说明也经常遇到障碍&#xff0c;比如…

MySQL | 往数据库中插入时间时,差了八个小时(时区设置)

一&#xff1a;问题 在往数据库中插入&#xff08;读取&#xff09;时间的时候&#xff0c;会相差八个小时&#xff0c;这是常见的问题&#xff0c;原因是因为时区设置的问题 二&#xff1a;知识点 UTC&#xff1a;Coordinated Universal Time 协调世界时。 GMT&#xff1a;…

AttributeError: module ‘jax‘ has no attribute ‘Array‘解决方案

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…