⽂件操作详解

⽬录
一    文件操作的引入
           1   为什么使⽤⽂件?
           2   什么是⽂件?
           3   文件分类(1 从⽂件功能的⻆度来分类:程序⽂件/数据⽂件 2根据数据的组织形式:为⽂本⽂件/⼆进制⽂件)
二    ⽂件的打开和关闭
           1     流和标准流(其中标准流在C语⾔程序启动的时候,默认打开)
           2    ⽂件指针(⽂件类型指针)
           3    ⽂件的打开和关闭
三    ⽂件的顺序读写
            1   fgect函数
            2   fputc函数
            3   fgets函数
            4   fputs函数
            5   fscanf函数
            6   fprintf函数
            7   fread函数
            8   fwrite函数
              
四    ⽂件的随机读写
             1  fseek函数
             2  ftell函数
             3  rewind函数
五    ⽂件读取结束的判定
             1  ⽂本⽂件读取是否结束/⼆进制⽂件的读取结束判断
             2  ⽂本⽂件的例⼦:
             3   ⼆进制⽂件的例⼦:
六    ⽂件缓冲区

一    文件操作的引入

1   为什么使⽤⽂件?

     为了将数据进⾏持久化的保存,如果我们没有文件我们写的程序的数据其实是存储在电脑的内存中,当我们程序一退出,内存回收,数据就会丢失,等再次运⾏程序,就看不到上次程序的数据。

2   什么是⽂件?

2.1  概念:磁盘(硬盘)上的⽂件是⽂件。

2.2 ⽂件名
⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤
⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀
例如: c:\code\test.txt
为了⽅便起⻅,⽂件标识常被称为⽂件名

2.3路径的两种形式(相当路径/绝对路径)

 

3 文件分类(1 从⽂件功能的⻆度来分类:程序⽂件/数据⽂件 2根据数据的组织形式:为⽂本⽂件/⼆进制⽂件)
3.1   从⽂件功能的⻆度来分类:
程序⽂件: 程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows环境后缀为.exe)。
数据⽂件 程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。
3.2  根据数据的组织形式
⼆进制⽂件:数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的⽂件中,就是⼆进制⽂件。
⽂本⽂件:如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂本⽂件

二     ⽂件的打开和关闭

  1   流和标准流(其中标准流在C语⾔程序启动的时候,默认打开)

1.1  流:因为不同的外部设备的输⼊输出操作各不相同,此时为了⽅便程序员对各种设备进⾏⽅便的操作便引出了流,其实,流就是为了⽅便程序员对各种设备读取数据或者输出数据的操作,而抽象出的概念,这里我们可以把流想象成流淌着字符的河。

1.2标准流的引入

在C语言中我们如何对针对⽂件、画⾯、键盘等的数据输⼊输出操作呢?其实C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。那为什么我们使用scanf和printf函数并没有直观的感觉到呢?这时候就要引入标准流。

1.3 标准流

C语⾔程序在启动的时候,默认打开了3个流:
stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。
stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出
流中。
stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。
stdin、stdout、stderr 三个流的类型是: FILE * ,通常称为⽂件指针
 
2   ⽂件指针(⽂件类型指针)

2.1  概念:

C语⾔中,我们就是通过 FILE* 的⽂件指针来维护流的各种操作的。我们在对文件进行操作时必须使用FILE*指针。 每个被使⽤的⽂件都在内存开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE。不同的C编译器的FILE类型包含的内容不完全相同,但是⼤同⼩异。

2.2 创建⼀个FILE*的指针变量

int main()

{
FILE* pf;//⽂件指针变量

return 0

}

定义pf是⼀个指向FILE类型数据的指针变量。我们可以使文件指针变量pf指向某个⽂件的⽂件信息区(是⼀个结构体变量)。通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与 它关联的⽂件
比如:

3    ⽂件的打开和关闭
3.1   ⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。所以我们使用文件的固定步骤打开⽂件、文件操作、关闭⽂件。这些过程需要FILE*的指针变量来连接,其实我们在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也就相当于建⽴了指针和⽂件的关系。而ANSI C 规定使⽤ fopen 函数来打开⽂件, fclose函数来关闭⽂件。

3.2使用文件的固定步骤

 fopen 函数原型:

 fclose函数原型:

3.3   文件的打开模式

其中常用的只要几个。

1

三    ⽂件的顺序读写

下面我们来介绍几个顺序读写函数,我们可以利用这几个顺序读写函数在结和文件的打开模式对文件进行操作。

顺序读写函数:

1   fgect函数

1.1  这是一个字符输入函数个,适用于所有输入流。

示例:

这里我们运用"r"只读的方式打开文件,这里我们是进行字符的读取,所以我们应在相应文件中放上内容  再看相应文件中的内容:

再看运行结果:

注意在读取字符时它会从第一个字符的位置开始读取,当每次读取完成后,光标会往后移动一位,利用这一特性,再利用循环进行读取,这样我们就可以达到像读取字符串一样,当我们想读取的个数比读取文件中的个数多会发生什么呢?这时候多余的会打印出错误信息(这里我就不举例了,感兴趣的可以自己试一试。特别注意fgetc在遇到空格时会选择跳过

 1.2    这个函数适用于使用输入流,那意味着对于标准流也有用。

这里我们先输入一个字符便可以打印出相应的字符

2   fputc函数

2.1 这是一个字符输出函数,适用于所有输出流。

示例:

现在我们打开文件观察其运行结果:

这里我们发现文件中已经有了相应的字符,但是我们·发现文件中的字符全部都在一行这是为什么呢?其实fputc函数也能识别”\0"只要其识别到”\0"结束标识符时才会换行。那这里有一个问题很值得我们思考,上面的fgect函数适用于使用输入流,是一个字符输入函数,而fputc函数这个函数适用于使用输出流,是一个字符输出函数。那么这两个函数是否呢结和使用呢?

fgect函数和fputc函数结和使用:

这里我们发现fgect函数和fputc函数结和使用结果是不行的,因为"w"模式是写入模式,会清空文件内容,在写入之后,在进行读取操作不会得到任何内容。

2.2 这个函数适用于使用输出流,那意味着对于标准流也有用。

3   fgets函数

这是一个文本行输入函数,适用于所有输入流。(文本行即能对一行操作)

这个函数有三个参数分别是存放读取字符串的地址、读取的字符个数、文件指针。

示例:

我们看一看文件中都内容:

 4  fputs函数

这是一个文本行输出函数,适用于所有输出流。(文本行即能对一行操作)

这个函数有两个参数分别是:字符串地址和文件指针

示例1:

结果:

示例2:

结果:
我们来比较一下上面两个代码运行结果我们观察看到输入的字符相同只是一个有换行一个没有,对应的结果便是有换行的结果在文件在分为两行没有换行的则在一行,所以 fputs函数是会识别换行符"\n"要想结果换行使用fputs函数就必须包含换行符。
5   fscanf函数

这是一个格式化输⼊函数函数,适用于所有输入流(格式化即特定的格式可以包含多个类型)

  我们发现这个函数的原型有些神奇,他的参数里面居然有个省略号!也就是说,它支持传入的参数个数是无限制的!要想熟练使用fscanf函数就得仿造scanf函数它们只相差一个参数fscanf函数比scanf函数多了一个文件指针。

示例:

文件内容:

运行结果:

6  fprintf函数

这是一个格式化输出函数,适用于所有输出流(格式化即特定的格式可以包含多个类型)

它的使用可以类比于printf函数比printf函数多了一个参数( 文件指针)

示例:

7   fread函数

这是一个⼆进制输⼊函数,适用于文件输入流。

这个函数传入的参数就相对来说复杂了一些:分别是存放字符串的地址、数据的字节大小、数据的数量、文件指针。

示例:

8 fwrite函数

 这是一个⼆进制输出函数,适用于文件输出流。

示例:

四    ⽂件的随机读写

1  fseek函数
这个函数可以根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)
int fseek ( FILE * stream, long int offset, int origin );

   第一个参数就是文件指针,没什么好说的,通过上前面的学习我们发现这种文件操作函数基本都要输入文件指针。

  第二个参数是偏移量参数,可以为正数,也可以为负数。

  第三个参数是起始位置

C语言为我们提供了 三个起始位置:
  • 文件头 SEEK_SET 0
  • 当前位置 SEEK_CUR 1
  • 文件尾 SEEK_END 2

2    ftell函数

 这个函数可以返回文件指针相对于起始位置的偏移量

long int ftell ( FILE * stream );

我们直接传文件指针就行,他会返回光标位置相较于文本最开始的偏移量 

rewind函数

这个函数可以让文件指针的位置回到文件的起始位置。

void rewind ( FILE * stream );

示例:

五    ⽂件读取结束的判定  

1⽂本⽂件读取是否结束/⼆进制⽂件的读取结束判断

我们都知道,EOF是文件结束的标志,那么feof呢?

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

⽂本⽂件的例⼦:

3   ⼆进制⽂件的例⼦:

运行结果:

    ⽂件缓冲区

缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。在C语言文件操作时,其实我们读取文件内容和输入内容到文件时,并不是直接对其进行操作的,而是通过文件缓冲区操作。那为什么会有⽂件缓冲区呢?其目的是为了提高编程效率假如没有⽂件缓冲区,这是我们要对一个字符串操作时如果没有⽂件缓冲区,我们就要不断对每个字符重复的进行操作,如果有了⽂件缓冲区我们把像输入的字符一个一个先放入缓冲区,等到积攒到了一定的数量,超过缓冲区范围,再把缓冲区的字符一次性放到硬盘中,这样就能减少系统的运行压力。记住缓冲区的⼤⼩根据C编译系统决定的。

本篇文章就到此结束,欢迎大家订阅我的专栏,欢迎大家指正,希望有所能帮到读者更好了解⽂件操作相关知识 ,觉得有帮助的还请三联支持一下~后续会不断更新C/C++相关知识,我们下期再见。

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

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

相关文章

gitee:解决vs文件权限被拒问题

报错问题 分析原因 git上传要忽略vs文件, Git因致命错误而失败。权限被拒绝 无法处理的路径。 解决方法 1、项目根目录下->右击空白->Open Git Bash here 2、 创建.gitignore文件 命令 touch .gitignore 3、 文件开头输入 .vs保存 参考地址 VS2017 Git fa…

【03】Selenium+Python 八种定位元素方法

操作元素,需要先查找定位到对应的元素。 查找单个元素:driver.find_element() 返回是一个web element 对象 查找多个元素:driver.find_elements() 返回是一个list对象 By 是 Selenium 中一个非常重要的类,用于定位网页元素。 使…

【linux学习指南】详解Linux进程信号保存

文章目录 📝保存信号🌠 信号其他相关常⻅概念🌉在内核中的表⽰ 🌠 sigset_t🌠信号集操作函数🌉sigprocmask🌉sigpending 🚩总结 📝保存信号 🌠 信号其他相关常…

Java安全—原生反序列化重写方法链条分析触发类

前言 在Java安全中反序列化是一个非常重要点,有原生态的反序列化,还有一些特定漏洞情况下的。今天主要讲一下原生态的反序列化,这部分内容对于没Java基础的来说可能有点难,包括我。 序列化与反序列化 序列化:将内存…

搭建一个基于Web的文档管理系统,用于存储、共享和协作编辑文档

搭建一个基于Web的文档管理系统,用于存储、共享和协作编辑文档 本项目采用以下架构: NFS服务器: 负责存储文档资料。Web服务器: 负责提供文档访问和编辑功能。SELinux: 负责权限控制,确保文档安全。Git服务器: 负责存储文档版本历史&#x…

智能堆叠,集群和IRF

堆叠和IRF其实可以近似看成同一种技术,只是华三叫IRF,华为叫智能堆叠 智能堆叠(iStack):支持堆叠特性的交换机通过堆叠线缆连接在一起,从逻辑上变成一台交换设备,作为一个整体参与数据转发&…

go使用mysql实现增删改查操作

1、安装MySQL驱动 go get -u github.com/go-sql-driver/mysql2、go连接MySQL import ("database/sql""log"_ "github.com/go-sql-driver/mysql" // 导入 mysql 驱动 )type Users struct {ID intName stringEmail string }var db *sql.DBfu…

springboot中使用mongodb完成评论功能

pom文件中引入 <!-- mongodb --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> yml中配置连接 data:mongodb:uri: mongodb://admin:1234561…

layui-vue第三方库表格列事件怎么写

插槽写入列点击事件 <div class"le-table-box" ref"TableBoxRef" :style"{ height: ShowPage ? calc(100% - 60px) : 100% }"><lay-table row-double"dbRowClick" :columns"TableColumn" :data-source"Table…

[在线实验]-Redis Docker镜像的下载与部署

镜像下载 dockerredis镜像资源-CSDN文库 加载镜像 使用以下命令从redis.tar文件中加载Docker镜像 docker load --input redis.tar 创建映射目录 为了确保Redis的数据能够持久化&#xff0c;我们需要创建一个本地目录来存储这些数据 mkdir -p datasource/docker/redis 运…

Flink CDC 使用实践以及遇到的问题

背景 最近公司在做一些业务上的架构调整&#xff0c;有一部分是数据从mysql采集到Starrocks&#xff0c;之前的一套方法是走 debezium 到 puslar 到 starrocks,这一套下来比较需要配置很多东西&#xff0c;而且出现问题以后&#xff0c;需要修改很多配置&#xff0c;而且现阶段…

配置idea环境进行scala编程

这里用的jdk是jdk-8u161,scala版本是2.12.0 在d盘新建一个本地仓库用来存放下载的maven包&#xff0c;在里面创建如下两个文件 更改settings文件为下面的样子 点击左下角的设置&#xff0c;更改maven本地仓库的位置&#xff08;默认在c盘用户目录下的.m2文件中&#xff0c;更改…

0017. shell命令--tac

目录 17. shell命令--tac 功能说明 语法格式 选项说明 实践操作 注意事项 17. shell命令--tac 功能说明 Linux 的 tac 命令用于按行反向输出文件内容&#xff0c;与 cat 命令的输出顺序相反。非常有趣&#xff0c;好记。也就是说&#xff0c;当我们使用tac命令查看文件内…

mimic插件使用

最近搞机械臂的末端夹具&#xff0c;本来想用吸盘的插件的&#xff0c;不知道为什么吸盘吸不起来可乐瓶&#xff0c;后面就换成夹爪了。 因为原厂的urdf文件中提供夹爪是用mimic标签控制剩下的5个joint关节的&#xff0c;网上参考的资料太少了&#xff0c;也是废了好多力 气&am…

Spring boot之BeanDefinition介绍

在spring框架中IOC容器进行bean的创建和管理。Bean的创建是一个比较复杂的过程&#xff0c;它并不像我们创建对象一样只是直接new一下就行&#xff0c;虽然有些bean确实就是New一下。但在Spring中可以通过一些途径对bean进行增强扩展。在这个过程中&#xff0c;BeanDefinition作…

redis基础spark操作redis

Redis内存淘汰策略 将Redis用作缓存时&#xff0c;如果内存空间用满&#xff0c;就会自动驱逐老的数据。 为什么要使用内存淘汰策略呢&#xff1f; 当海量数据涌入redis&#xff0c;导致redis装不下了咋办&#xff0c;我们需要根据redis的内存淘汰策略&#xff0c;淘汰一些不那…

【MyBatis】验证多级缓存及 Cache Aside 模式的应用

文章目录 前言1. 多级缓存的概念1.1 CPU 多级缓存1.2 MyBatis 多级缓存 2. MyBatis 本地缓存3. MyBatis 全局缓存3.1 MyBatis 全局缓存过期算法3.2 CacheAside 模式 后记MyBatis 提供了缓存切口&#xff0c; 采用 Redis 会引入什么问题&#xff1f;万一遇到需强一致场景&#x…

力扣--LCR 150.彩灯装饰记录II

题目 代码 if(root null){ return new ArrayList<>(); } Queue<TreeNode> queue new LinkedList<>();List<List<Integer>> res new ArrayList<>();queue.add(root);while(!queue.isEmpty()){int k queue.size();List<Integer> …

RFdiffusion Potential类解读

1. Potential 类 功能 Potential 是一个接口类(抽象类),用于定义潜在函数的接口,要求继承它的类必须实现 compute 方法。它的设计遵循 面向对象编程的多态性原则,通过抽象接口确保子类实现特定功能,同时定义了一个通用的 API(即 compute 方法)。源代码: class Poten…

一款.NET开源的Windows资源管理器标签页工具

前言 今天大姚给大家分享一款基于.NET开发的可以让你在Windows资源管理器中使用Tab多标签功能的小工具&#xff1a;QTTabBar。 工具介绍 QTTabBar是一款基于.NET开发的可以让你在Windows资源管理器中使用Tab多标签功能的小工具。从此以后工作时不再遍布文件夹窗口&#xff0c…