文件操作<C语言>

news2024/11/27 0:39:11

导言

        平时我们在写程序时,在运行时申请内存空间,运行完时内存空间被收回,如果想要持久化的保存,我们就可以使用文件,所以下文将要介绍一些在程序中完成一些文件操作。


目录

导言

文件流

文件指针

文件的打开与关闭

打开:

关闭:

文件操作

顺序读写:

单个字符:

fputc函数

 fgetc函数

字符串:

 fputs函数

  fgets函数

格式化:

  fprintf函数

fscanf函数

其他:

  sprintf函数

 

sscanf函数

随机读写:

fseek函数

 ftell函数

 rewind函数

 文件结束判定

feof函数

 ferror函数


文件流

        我们常使用的是标准流,它们在使用C语言编写程序时已经默认打开:

●stdin—标准输入流,大部分从键盘输入,比如scanf函数

●stdout—标准输出流,大部分从显示器输出,比如printf函数

●stderr—标准错误流,大部分从显示器输出

 这三种流,属于FILE*类型的指针,我们常常称为文件指针。


文件指针

        文件指针FILE*都指向了一个包含文件信息的结构体。

每个被使用的文件都会自动开辟一个文件信息区,这个文件信息区存放着文件的各种信息,他被存放在一个结构体中,结构体的类型是由系统命名的,命名为FILE。

vs2013这个文件类型声明
struct _iobuf {
 char *_ptr;
 int _cnt;
 char *_base;
 int _flag;
 int _file;
 int _charbuf;
 int _bufsiz;
 char *_tmpfname;
};
typedef struct _iobuf FILE;//typedef重命名struct _iobuf为FILE

这样我们在后面使用时创建一个FILE*型的指针,就可以指向任意一个文件信息区(结构体变量)了。

放一张bit课件的图:


文件的打开与关闭

        前面我们提到在C语言中默认打开的流只有标准流,那么我们想要完成文件操作时,那么我们就得先打开文件流,在完成操作后再关闭文件流。

打开:

使用函数fopen()打开文件

函数参数及其返回值

FILE* fopen(const char* filename,const char* made);
//filename:文件名(文件路径)
//made:打开方式
//返回值:FILE*,一个指向filename文件信息区的文件指针,执行失败返回NULL

注意点

●关于参数filename两种表达方式:

绝对路径:从根目录开始创建(C/D盘),任何文件都可访问,如:c:\code\test.txt

在C语言中地址是个字符串,\会被当做转义字符,那么我们可以使用\\或者/的方式来代替

相对路径:以当前路径为基础访问,“.”表示当前路径,“..”表示上一层路径。如:
假设我的当前路径为c:\cyuyan\code\test.txt
我的桌面路径:c:\cyuyan\code\desktop
我想用相对路径访问我的桌面:..\desktop\
相对路径在本目录访问文件时常常会省略.\,直接使用文件名+后缀的方式访问
●关于常用参数mode:
●为了输入(读)数据, mode为“r”,存在:打开,不存在:报错
●为了输出(写)数据,并将目标文件内容清空, mode为“w”,存在:打开,不存在:新建一个

使用举例:

文件运行程序前:

 运行程序:

 文件运行程序后:

关于文件打开值得注意的是:mode的参数决定了后续的文件操作的权限,以读的方式打开只能进行一些读的操作,以写的方式打开只能进行一些写的操作。


关闭:

使用函数fclose()关闭文件

函数参数及其返回值

int fclose(FILE* stream);
//stream:文件流
//返回值:成功:0,失败:EOF(-1)

文件打开后不关闭会造成内存泄漏,这与动态内存不free是一个道理,最后记得置NULL。

使用举例:


文件操作

顺序读写:

单个字符:

fputc函数

功能:写单个字符到流。(输出——写)

 函数参数及其返回值

int fputc(int character ,FILE* stream);
//character:单个字符
//stream:文件流
//返回值:成功:写入字符的ASCII码值,失败:EOF(-1)

使用举例:

当前目录下的test.txt文件内容:


 fgetc函数

功能:从流读单个字符。(输入——读)

 函数参数及其返回值

int fgettc(FILE* stream);
//stream:文件流
//返回值:成功:读取字符的ASCII码值,失败:EOF(-1)

使用举例:

我们先在当前目录创建一个test.txt文件,并写入字符b保存。

运行程序打印出fgetc的返回值(这个返回值就是文件内字符的ASCII码值):

 小写字母b的ASCII码值为98,说明我们读取成功。

值得注意的是fgetc和fputc函数只是针对单个字符的,所以文件存在多个字符时,读取时是第一个字符。


字符串:

 fputs函数

功能:写字符串到流。(输出——写)

 函数参数及其返回值

int fputs(const char* str,FILE* stream);
//str:要写入的字符串
//stream:文件流
//返回值:成功:非负整数,失败:EOF(-1),设置errorno

使用举例:

返回0,也是一个非负整数,且大部分编译器都返回0。

 test.txt文件的写入情况:


  fgets函数

功能:从流中读取字符串。(输入——读)

 函数参数及其返回值

char* fgets(const char* str, int num ,FILE* stream);
//str:从流中读取的字符放在这里面
//stream:文件流
//num:读取num-1个字符,最后一个放\0,
//返回值:成功:字符串str首地址,失败:NULL

注意点:

●遇到换行符停止读取,且这个换行符也会被读取到str中,所以在一些特定场景下,为了输出格式别忘了替换掉换行符\n。

●fgets函数还常常运用于标准输入流,因为它只有读取到\n时才停止,会读取空格,使用时,stream参数为stdin。

使用举例:

创建一个存放着两行数据的test.txt文件:

运行fgets程序:

 我们看到它的确读取成功了,打印时没有加\n,打印出来却自动换行了,说明读取了\n,验证了前面的注意点,我们可以看Debug看一下:

值得注意的是fgets还常常用于完成一些标准输入的操作,它会读取空白字符,且它比gets安全。


格式化:

  fprintf函数

功能:格式化数据到流。(输出——写)

 函数参数及其返回值

int fprintf(FILE* stream , const char* format,……);
//stream:文件流
//format:与printf函数中的“字符串”类似,可以放入占位符
//……:可变参数列表,与printf类似
//返回值:成功:写入字符数,失败:EOF(-1)

使用举例:

运行程序后:

fprintf函数与printf函数类似,只是在参数部分多出了文件流,其他参数不变,返回值也是。


fscanf函数

功能:从流中读取格式化数据。(输入——读)

 函数参数及其返回值

int fscanf(FILE* stream , const char* format ,……);
//stream:文件流
//format:"占位符"与scanf函数第一个参数类似
//……:可变列表(变量名)
//返回值:成功:读取个数,失败:EOF(-1)

使用举例:

创建一个test.txt文件,并写入数据:

 运行程序:

可以观察到,fscanf函数与scanf函数类似,只是多出文件流参数, 其他与scanf函数类似,且需要取地址&


其他:

  sprintf函数

功能:格式化数据到字符串。(输出)

 函数参数及其返回值

int sprintf(char* str, const char* format,……);
//str:要写入的字符串
//format:与printf函数中的“字符串”类似,可以放入占位符
//……:可变参数列表,与printf类似
//返回值:成功:写入字符数,失败:EOF(-1)

使用举例:


 
sscanf函数

功能:从字符串格式化数据。(输入)

 函数参数及其返回值

int sscanf(char* str, const char* format,……);
//str:要读取的字符串
//format:与scanf函数中的“字符串”类似,可以放入占位符
//……:可变参数列表,与scanf类似
//返回值:成功:读取项数,失败:EOF(-1)

使用举例:

 这两个函数可以简单理解为字符串与格式化数据的互换函数。


随机读写:

fseek函数

功能:改变光标位置

 函数参数及其返回值

int fseek(FILE* stream , long int offset ,int origin)
//stream:文件流
//offset:相对于参数origin的偏移量
//origin:三个选项:SEEK_SET:文件指针起始位置、SEEK_CUR:文件指针当前位置、SEEK_END:文件指针结束位置
//返回值:成功:0,失败:非0整数并设置errorno

使用举例:

我们先创建一个文件存放helloworld 18:

 运行程序:


 ftell函数

功能:返回文件指针相对于起始位置的偏移量

 函数参数及其返回值

long int ftell(FILE* stream);
//stream:文件流
//返回值:偏移量

使用举例:

 

 


 rewind函数

功能:使文件指针回到起始位置

 函数参数及其返回值

void rewind(FILE* stream);
//stream:文件流
//返回值:无

使用举例:


 文件结束判定

feof函数

功能:判断文件结束原因(返回值0:遇到错误,非0:遇到文件尾)

 函数参数及其返回值

int feof(FILE* stream);
//stream:文件流
//返回值:0:遇到错误,非0:遇到文件尾

使用举例:


 

 ferror函数

功能:判断文件错误状态

 函数参数及其返回值

int feof(FILE* stream);
//stream:文件流
//返回值:非零值(1):遇到错误,0:没错误

这应该是我所有博客中最长的一篇,因为是笔记的原因,然后也不太熟,所以前前后后几天花了6、7小时,最后也没来的及检查一遍,请佬们斧正,封面图是ai生成的。

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

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

相关文章

Android 开发必备知识点及面试题汇总(Android+Java+算法+性能优化+四大组件……

**虚引用:**顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。 7.介绍垃圾回收机制 **标记回收法:**遍历对象图并且记录可到达的对象&#xff0c…

WPS没保存关闭了怎么恢复数据?4个方法(更新版)

想象一下,你正在用WPS奋笔疾书,灵感如泉水般涌出,突然间,电脑却跟你开了个玩笑——啪地一下,文档未保存就关闭了!是不是感觉像是被泼了一盆冷水,所有的热情瞬间熄灭?别急&#xff0c…

为 Android 应用打造精良的 Chrome OS 使用体验

override fun onKeyUp(code: Int, ev: KeyEvent?): Boolean { return when (code) { KeyEvent.KEYCODE_J -> { // Do something here true } else -> super.onKeyUp(code, ev) // 重要!! } } 注意我们标出 “重要” 的那一行代码。这行代…

20240623 每日AI必读资讯

🤖原生鸿蒙AI浓度要爆表了! - 一年一度华为开发者大会上,余承东首次揭秘“鸿蒙原生智能”Harmony Intelligence! - 华为小艺进化成系统级智能体。 - 一句话实现跨多个应用的规划和任务执行;在第三方APP上随意处理文…

Unity的渲染管线

渲染管线 概念 Unity的渲染管线是在图形学渲染管线的基础上,加上了高度可配置可扩展的框架,允许开发者自定义渲染流程。 渲染管线(渲染流水线)概述:将数据分阶段的变为屏幕图像的过程。 数据指的是模型、光源和摄像…

C++ | Leetcode C++题解之第174题地下城游戏

题目&#xff1a; 题解&#xff1a; class Solution { public:int calculateMinimumHP(vector<vector<int>>& dungeon) {int n dungeon.size(), m dungeon[0].size();vector<vector<int>> dp(n 1, vector<int>(m 1, INT_MAX));dp[n][m …

【从0实现React18】 (二) JSX 的转换 jsx到底是什么?React是如何把jsx转换为ReactElement?

react项目结构 React(宿主环境的公用方法)React-reconciler(协调器的实现&#xff0c;宿主环境无关)各种宿主环境的包shared(公用辅助方法&#xff0c;宿主环境无关) 当前实现的JSX转换属于 react****包 初始化react包 先创建react package并初始化 更新package.json文件&a…

Redis源码学习:quicklist的设计与实现

为什么需要quicklist 假设你已经知道了ziplist的缺陷&#xff1a; 虽然节省空间&#xff0c;但是申请内存必须是连续的&#xff0c;如果内存占用比较多&#xff0c;申请效率低要存储大量数据&#xff0c;超过了ziplist的最佳上限后&#xff0c;性能有影响 借鉴分片思想&…

仓颉编程语言入门

华为在 2024 年 6 月 21 日的华为开发者大会上&#xff0c;华为终端 BG 软件部总裁龚体正式官宣了华为自研仓颉编程语言&#xff0c;并发布了 HarmonyOS NEXT 仓颉语言开发者预览版。 仓颉编程语言文件后缀名为 .cj, 以下是第一个入门代码输出&#xff1a;你好&#xff0c;仓颉…

理解 什么是 滚动更新,蓝绿部署,灰度发布 以及它们的区别

滚动更新&#xff0c;蓝绿部署&#xff0c;灰度发布 这3种 现代化的 发布模式相信很多人都听过&#xff0c; 但是并不是都能正确理解他们的作用和区别 滚动更新 Rolling Update 所谓滚动更新是for 那些多实例的service的。 假如1个 service 有n 个instance, 更新时并不是n 个…

xss.haozi.me靶场通关参考

url&#xff1a;https://xss.haozi.me/ 文章目录 0x000x010x020x030x040x050x060x070x080x090x0A0x0B0x0C00xD00xE00xF0x100x110x12 0x00 先看js代码&#xff0c;第一关给你热热手&#xff0c;没给你加过 payload&#xff1a; <script>alert(1)</script>0x01 这…

移动端 UI 风格,诠释精致

移动端 UI 风格&#xff0c;诠释精致

文华财经wh7关于mancd和KDJ预警指标公式源码

一、零轴下金叉和零轴上死叉的预警 MA5:MA(C,5); MA10:MA(C,10); DIFF:EMA(CLOSE,12) - EMA(CLOSE,26); DEA:EMA(DIFF,9); MACD:2*(DIFF-DEA); CROSS(MA5,MA10)&&MAX(DIFF,DEA)<0,NOTICE(零轴下金叉); CROSSDOWN(MA5,MA10)&&MIN(DIFF,DEA)>0,NOTI…

华为---理解OSPF Route-ID(五)

9.5 理解OSPF Route-ID 9.5.1 原理概述 一些动态路由协议要求使用Router-ID作为路由器的身份标示&#xff0c;如果在启动这些路由协议时没有指定Router-ID,则默认使用路由器全局下的路由管理Router-ID。 Router-ID选举规则为&#xff0c;如果通过Router-ID命令配置了Router-…

46、基于自组织映射神经网络的鸢尾花聚类(matlab)

1、自组织映射神经网络的鸢尾花聚类的原理及流程 自组织映射神经网络&#xff08;Self-Organizing Map, SOM&#xff09;是一种用于聚类和数据可视化的人工神经网络模型。在鸢尾花聚类中&#xff0c;SOM 可以用来将鸢尾花数据集分成不同的类别&#xff0c;同时保留数据间的拓扑…

centos7系统上安装MySQL8.4图文教程

本章教程&#xff0c;主要记录如何在CentOS7系统上安装MySQL8.4的详细步骤。 一、查看当前系统版本 cat /etc/centos-release二、安装步骤 1、创建mysql目录 cd /usr/local && mkdir mysql && cd mysql2、安装rpm包 yum install https://repo.mysql.com//m…

[FreeRTOS 基础知识] 互斥访问与回环队列 概念

文章目录 为什么需要互斥访问&#xff1f;使用队列实现互斥访问休眠和唤醒机制环形缓冲区 为什么需要互斥访问&#xff1f; 在裸机中&#xff0c;假设有两个函数&#xff08;func_A, func_B&#xff09;都要修改a的值&#xff08;a&#xff09;&#xff0c;那么将a定义为全局变…

Django数据驾驶舱

Django数据驾驶舱 1.项目介绍2.项目结构3.库表结构3.1 appcsdn的models3.2 appssq的models3.3 appweather的models3.4 appweibo的models 4.功能展示5.解决问题5.1 路由配置5.2 后端数据与前端echarts展示5.3 长图表丝滑滚动条 6.遗留问题7.资源分享 1.项目介绍 这里介绍本人最…

STM32读写备份寄存器和实时时钟

文章目录 1. 硬件电路 2. RTC操作注意事项 操作步骤 3. 代码实现 3.1 读写备份寄存器 3.1.1 main.c 3.2 实时时钟 3.2.1 MyRTC.c 3.2.2 MyRTC.h 3.2.3 main.c 1. 硬件电路 对于BKP备份寄存器和RTC实时时钟的详细解析可以看下面这篇文章&#xff1a; STM32单片机BKP备…

水果销售系统

摘 要 随着电子商务的快速发展&#xff0c;传统的实体销售模式面临着越来越多的挑战。在这个数字化的时代&#xff0c;消费者的购物习惯发生了翻天覆地的变化&#xff0c;消费者更倾向于在家中通过网络平台浏览并购买商品&#xff0c;这无疑给传统水果销售带来了极大的挑战。为…