C语言文件操作函数详细解说

二进制文件和文本文件

       二进制文件就是以二进制的形式写入文件的,人是看不懂的,而文本文件就是以ACSLL码的形式进行保存的。
举个例子,10000这个数字如果保存在二进制文件中就应该是0010 0111 0001 0000 ,占四个字节;而在文本文件中则是以ACSLL码的形式保存,就是说明文本文件就是我们人正常看到的文字,10000就是以10000 的形式进行保存的,占5个字节。

       当文件或者其他设备的内容需要通过计算机来写入或者读取到其他设备的时候,就需要知道怎么打开对应的通道,因为不同设备的转存需要不同的通道,例如光盘的数据要写到硬盘上和硬盘的数据要写到U盘上,都是需要不同的通道进行的

而流就是数据流,为了提高程序员的工作效率和学习便利,在计算机底层设计了一个流,它就是可以将不同的设备连接到其他的设备,实现数据的读取写入等操作,我们程序员只需要关心流是怎么打开关闭和怎么通过流写入读写的,知道这个就不用关心这个设备和另一个设备需要什么通道才能连接,这些计算机的底层已经设计好了。

文件的打开和关闭

       文件的使用分三个步骤,打开文件,文件的读写操作,文件的关闭。

fopen

fopen 函数是用来打开文件的。filename 就是文件的名
当然文件也会有打开失败的情况,一旦打开失败就会返回空指针,我们只要写一段代码来避免空指针的解引用就可以了。
mode 是打开文件的形式,我们来看一下文件的打开形式:

⽂件使⽤⽅式 含义 如果指定⽂件不存在
“r”(只读) 为了输⼊数据,打开⼀个已经存在的文本文件 出错
“w”(只写) 为了输出数据,打开⼀个文本文件 建立⼀个新的文件
“a”(追加) 向⽂本⽂件尾添加数据 建立⼀个新的文件
“rb”(只读) 为了输⼊数据,打开⼀个二进制文件出错
“wb”(只写) 为了输出数据,打开⼀个二进制文件 建立⼀个新的文件
“ab”(追加) 向⼀个二进制文件尾添加数据 建立⼀个新的文件
“r+”(读写) 为了读和写,打开⼀个文本文件 出错
“w+”(读写) 为了读和写,建议⼀个新的⽂件 建立⼀个新的文件
“a+”(读写) 打开⼀个文件,在文件尾进行读写 建立⼀个新的文件
“rb+”(读写) 为了读和写打开⼀个二进制文件 出错
“wb+”(读写)为了读和写,新建⼀个新的二进制文件 建立⼀个新的文件
“ab+”(读写)打开⼀个二进制文件,在文件尾进行读和写 建立⼀个新的文件

fclose

fclose 是文件关闭函数,这个函数的使用比较便捷,我们值需要传入文件名即可。

文件缓冲区

       在文件操作中,计算机会为文件开辟一个缓冲区(缓冲区的大小有C语言编译器决定的),只有缓冲区已满或者刷新缓冲区的时候,操作系统才会把缓冲区的数据输入到你设定的目标空间上。
       因为操作系统上运行很多程序,不可能一直为编译器服务,所以设立了一个缓冲区来暂时存储数据,这样操作系统的运行效率才不会因为编译器而变得低下。

这就是为什么文件打开后需要关闭文件,如果不关闭就会一直占用空间。

文件顺序读写函数

字符输入

fgetc

字符输入函数,适用于所有输入流

从流里面得到单个字符,返回值是整型的原因是字符可以用ACSLL码值来表示,而且当读取失败或者文件末尾是会返回EOF(也就是 -1),所以使用 int 为返回类型。

实践:

fputc

字符输出函数,适用于所有输出流

如果写入失败就会返回EOF

实践:

文本行操作

fgets

文本行输入函数,适用于所有输入流

fgets 会从流里面读取字符串,一旦遇见换行或者文件末尾就会停止读取
str 是读取到的字符串保存的地址,num是读取的个数,stream 就是流。
当读取成功的时候就会返回 str 这个地址,否则就会返回空指针!

读取的字符会在末尾自动添加 \0,所以你实际读取到的字符个数实际上是 num - 1

实践一下:

fputs

文本行输出函数,适用于所有输出流

fputs 是写一个字符串到流里面,参数str 就是你要输入的字符串内容的地址, stream 就是流。注意返回值是 int 类型的,如果写入成功就会返回一个非负值,如果失败就会返回EOF(-1)并且会标记错误的指示。

实践一下:

一组函数的对比

       这里我们需要对比 scanf / printf 和 fscanf / fprintf 和sscanf / sprintf 的函数使用。scanf 和 printf 想必大家都知道这是标准的输入输出函数!

fscanf

格式化输入函数,适用于所有输入流

fsacnf 是可以从指定的流里面输入格式化的数据。它和scanf 最大的区别就是可以指定流,因此也就多了个参数 stream ,这个流也可以是标准流。

实践:

fprintf

格式化输出函数,适用于所有输出流

fprIntf 是可以输出格式化的数据到指定的流里面。它和 printf 最大的区别就是可以指定流,因此也就多了个参数 stream ,这个流也可以是标准流。

实践:

sscanf

适用于字符串,可以将字符串的数据以格式化的形式读取

它和 scanf 最大的区别就是 sscanf 是可以指定的字符串,因此也就多了个参数str (字符串的地址)

实践:

sprintf

适用于字符串,可以将格式化数据输出到字符串中

它和 printf 最大的区别就是 sprintf 是指定的字符串,因此也就多了个参数str (字符串的地址)

实践:

综合应用:

二进制的读写函数

fread

二进制输入,适用于文件

这个函数会将文件中的数据以二进制的形式写入到字符串中。
size 是指一个数据多大,count 表示有多少个数据需要写入。

实践:

#include <stdio.h>int main()
{FILE* pf = fopen("data.txt", "rb");if (pf == NULL){perror("fopen()");return 1;}int arr[20] = { 0 };fread(arr, sizeof(arr[0]), 20, pf);fclose(pf);return 0;
}

fwrite

二进制输出,适用于文件

把数据以二进制的形式写入流中

实践:

文件随机读写函数

       当文件在读写操作中,会有指针的移动(也可以理解成光标的移动)它决定了读写下一个数据,为了使程序能更加灵活的掌控,C语言引入了随机读写函数,这些函数可以控制光标的移动。

fseek

这个函数可以移动光标。
解释一下参数部分:offset 是你想移动多少的(正数表示向后移动光标,负数表示向前移动光标),origin 是你想从哪里开始移动(这里给了三个参数,SEEK_SET 是文件的起始位置,SEEK_CUR 是文件的当前位置,SEEL_END 是文件的末尾)

我们来实践一下:

#include <stdio.h>int main()
{FILE* pf = fopen("data.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件int ch = fgetc(pf);printf("%c\n", ch);fseek(pf, 5, SEEK_SET);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, 4, SEEK_CUR);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, -4, SEEK_END);ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}

ftell

这个函数是获得当前光标的位置。

rewind

这个函数比较简单,就是能将光标移动回原来的位置。只需要传入文件指针即可。

文件读写结束判定

       在文件读取的过程中有两种情况会导致文件读取结束,一个是遇到文件末尾,一个是读取过程中遇到障碍导致没能遇到文件末尾而体纤导致文件读取失败。在上面的函数讲解中我们提到过文件读取结束回返回一个数值(有EOF,NULL等),并且如果不是正常的读取结束是回标记的,而且官方文档中有提到 ferf 这个函数,它就是来判断文件的读取结束时因为什么原因而结束的。

feof

feof 需要接收的参数就是文件指针,返回值有两种,一个是 非零值 (说明文件是遇到文件末尾正常读取完成而结束的);另外一种则是 0 (说明文件没有遇到文件末尾而导致结束)

有了这个函数,我们就可以判断文件读取结束后是不是遇到文件末尾的结束的!!!

实践:

#include <stdio.h>int main()
{FILE* pf = fopen("data.txt", "r");if (pf == NULL){perror("fopen()");return 1;}char ch;while ((ch = fgetc(pf)) != EOF){printf("%c", ch);}if (feof(pf)){printf("文件不是遇到文件末尾而结束的!\n");}else{printf("文件正常读取而结束!\n");}fclose(pf);pf = NULL;return 0;
}

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

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

相关文章

【随笔】Git 基础篇 -- 分支与合并(九)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

Kubernetes(k8s):部署、使用 metrics-server

Kubernetes&#xff08;k8s&#xff09;&#xff1a;部署、使用 metrics-server 一、metrics-server简介二、部署metrics-server2.1、 下载 Metrics Server 部署文件2.2、修改metrics-server.yaml 文件2.3、 部署 Metrics Server2.4、 检查 Metrics Server 三、使用 Metrics Se…

Windows 上路由、端口转发配置,跨网络地址段

一、背景 有时候我们会遇到这样的场景&#xff0c;一批同一局域网中只有某一台主机带外且系统为windows&#xff0c;局域网中其他非带外的主机要想访问外网&#xff0c;本文将介绍如何配置在带外主机上开启路由及端口转发。 二、配置操作 2.1、带外主机开启路由转发 1&#x…

LeetCode 209 长度最小的子数组(滑动窗口,双指针实现)

给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xff1a; 输入&…

使用C++调用讯飞星火API的详细指南

正文&#xff1a; 科大讯飞是中国领先的人工智能公司&#xff0c;其讯飞星火API为开发者提供了丰富的接口和服务&#xff0c;支持各种语音和语言技术的应用。下面是使用C接入讯飞星火API的步骤和代码示例。 步骤一&#xff1a;注册账号并创建应用 首先&#xff0c;您需要访问科…

Java 线程的状态

线程状态 操作系统的线程 从上图可以详细分析出线程的五种状态以及状态之间的切换。 1&#xff09;新建状态&#xff08;New&#xff09;&#xff1a;当线程对象对创建后&#xff0c;即进入了新建状态&#xff0c;如&#xff1a;Thread t new MyThread(); 2&#xff09;就绪…

【单片机家电产品学习记录--红外线】

单片机家电产品学习记录–红外线 红外手势驱动电路&#xff0c;&#xff08;手势控制的LED灯&#xff09; 原理 通过红外线对管&#xff0c;IC搭建的电路&#xff0c;实现灯模式转换。 手势控制灯模式转换&#xff0c;详细说明 转载 1《三色调光LED台灯电路》&#xff0c…

java的警示之有危险的行为

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;&#x1f468;&#x1f3fb;‍&#x1f393;告别&#xff0c;今天 &#x1f4d4;高质量专栏 &#xff1a;☕java趣味之旅 欢迎&#x1f64f;点赞&#x1f5e3;️评论&#x1f4e5;收藏&#x1f493;关注 &#x1f496;衷心的希…

【JavaSE】类和对象详解(下)

前言 面向对象程序的三大特性&#xff1a;封装、继承、多态~ 书接上回 类和对象&#xff08;上&#xff09;~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 封装 private public 快速生成可访问封装的方法 包…

Mybatis plue(二) 核心功能

核心功能 P5 条件构造器 mybatisplus支持各种复杂的where条件&#xff0c;可以满足日常开发的所有需求 wrapper就是条件构造器,wrapper就是顶层的&#xff0c; 示例&#xff1a; 查询出名字带0&#xff0c;存款大于等于1000的人的id,username,info,balance字段 Testvoid te…

Redis高可用与持久化

一、Redis高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证…

Ubuntu20.04安装MatlabR2018a

一、安装包 安装包下载链接 提取码&#xff1a;kve2 网上相关教程很多&#xff0c;此处仅作为安装软件记录&#xff0c;方便后续软件重装&#xff0c;大家按需取用。 二、安装 1. 相关文件一览 下载并解压文件后&#xff0c;如下图所示&#xff1a; 2. 挂载镜像并安装 2…