c语言中的文件操作(2)
文件的打开-fopen
函数介绍
文件的打开方式
相对路径与绝对路径
文件关闭函数fclose
文件操作的正确流程
函数的介绍
文件的打开形式
相对路径与绝对路径
文件的关闭函数-fclose
正确的文件操作的流程
前言
通过前面的章节我们已经知道文件的基本的概念,我们如何通过代码对文件进行操作呢?比如我们如何打开文件,关闭文件,已经在文件中写入以及读取数据呢?
在头文件stdio.h中包含了一系列的文件操作函数,以便我们对特定的文件进行相应的操作。学会对文件进行操作后,我们就可以将代码与文件联系起来,这样能让编程变得更有意思不是吗?比如你可以用代码写一个游戏,当游戏结束后可以将游戏当前的数据保存到一个文件中,那么当你下一次运行代码时只要先读取该文件中的数据,就可以接着上一次的游戏进度继续玩,而不至于从头再来。
下面介绍了打开以及关闭文件的操作函数,以及其中的一些细节。
文件打开函数–fopen
函数的介绍
FILE * fopen ( const char * filename, const char * mode );
该函数的功能就是打开一个文件,函数的第一个参数是你要打开的文件的文件名,第二个参数是打开这个文件的形式。
我们知道打开一个文件时,系统会为该文件创建一个文件信息区,该函数调用完毕后,如果打开该文件成功,那么返回指向该文件信息区的指针(FILE*类型);如果打开文件失败,那么返回一个空指针(NULL)。
打开方式如下:

使用上面的模式说明符,文件将作为文本文件打开。为了将文件作为二进制文件打开,模式字符串中必须包含“b”字符。这个附加的“b”字符可以附加在字符串的末尾(从而形成以下复合模式:“rb”、“wb”、“ab”、“r+b”、“w+b”、“a+b”),也可以插入在“+”符号之前(“rb+”、“wb+”、“ab+”)。
如果序列后面有其他字符,则行为取决于库实现:一些实现可能会忽略其他字符,例如,接受额外的“t”(有时用于显式表示文本文件)。
在某些库实现中,使用更新模式打开或创建文本文件可能会视为二进制文件。
举个几个例子:
1.若我们要以文本形式打开一个名叫test.txt的文件,将要对其进行输入操作,那么打开文件时应该这样写:
FILE* pf = fopen("test.txt", "r");
该文件必须存在,否则会返回空指针。
2.若我们要以二进制打开一个名叫test.txt的文件,将要对其进行输出操作,那么打开文件时应该这样写:
FILE* pf = fopen("test.txt", "wb");
注意一点就是如果该文件不存在则将会自己创建一个名叫test.txt的文件。
二、检测fopen返回值的有效性
前面说到,如果文件打开成功,fopen函数会返回指向文件信息区的指针,否则fopen函数会返回一个空指针。所以当使用接收fopen函数的返回值的指针前,我们必须检测其有效性,否则可能非法访问内存。
检测有效性:
int main()
{FILE* pf = fopen("test.txt", "r");if (NULL == pf){perror(fopen);return 1;}return 0;
}
文件的相对路径与绝对路径
填写fopen函数的第一个参数的时候,如果我们要打开的文件与我们正在运行的源代码在同级目录下(以打开text.txt文件为例),那么我们应该这样写:
FILE* pf = fopen("test.txt", "r");
但是如果打开的文件与当前运行的文件不在同一个目录内,我们分为相对路径和绝对路径。
一相对路径
当待打开的文件位于正在运行的源代码的上一级时:
FILE* pf = fopen("../test.txt", "r");
当待打开的文件位于正在运行的源代码上上级的时候:
FILE* pf = fopen("../../test.txt", "r");
当待打开的文件位于正在运行的源代码下一级的时候:
FILE* pf = fopen("debug/test.txt", "r");
注意的是这里的test文件位于debug内,debug文件与正在运行的源代码在同级目录下。
总结:
要打开上级的文件在原来的基础上加上". ./“,再上一级再加一个”. ./",以此类推。
要打开下级的文件,就需从源代码这一级开始,写出目标文件的路径。
二、绝对路径
有博友可能觉得相对路径的方法比较麻烦(可能还要去数目标文件与源文件相差的级数),绝对路径就没那么麻烦了,绝对路径就直接写出目标文件的完整路径即可,例如:
FILE* pf = fopen("D:\\code\\File_function\\File_function\\data.txt", "r");
文件关闭函数 - fclose
与动态开辟内存空间时一样,当我们打开文件时,会在内存中开辟一块空间,如果我们打开该文件后不关闭,那么这个空间会一直存在,一直占用那块内存空间,所以当我们对一个文件的操作结束时,一定要记住将该文件关闭。这就需要用到fclose函数来关闭文件。
int fclose ( FILE * stream )
我们如果要关闭一个文件,那么直接将该文件的文件指针传入fclose函数即可,fclose函数如果关闭文件成功会返回0。与free函数一样,当我们调用完fclose函数将文件关闭后,我们也要将指向文件信息区的指针置空,避免该指针变成野指针。
文件操作正确流程
知道了如何打开文件和关闭文件,也就相当于知道了如何进入和如何出去,所以当我们要对一个文件进行操作的时候,正确的流程应该是这样的:
int main()
{FILE* pf = fopen("test.txt", "r");if (NULL == pf){perror(fopen);return 1;}//对文件的一系列操作//关闭文件fclose(pf);pf = NULL;return 0;
}
相关文章:
c语言中的文件操作(2)
文件的打开-fopen 函数介绍 文件的打开方式 相对路径与绝对路径 文件关闭函数fclose 文件操作的正确流程 函数的介绍 文件的打开形式 相对路径与绝对路径 文件的关闭函数-fclose 正确的文件操作的流程 前言 通过前面的章节我们已经知道文件的基本的概念,我们如…...
【Verilog】case、casex、casez的区别
在case语句中,敏感表达式中与各项值之间的比较是一种全等比较,每一位都相同才认为匹配。 在casez语句中,如果分支表达式某些位的值为高阻z,那么对这些位的比较就会忽略,不予考虑,而只关注其他位的比较结果…...
Seata源码笔记(二)
Seata源码笔记(二) 配置相关的ConfigurationFactory静态代码块load():融入spring获取value的方式Configuration的get方法拦截后,value取值优先级ObjectHolderPROPERTY_BEAN_MAP getInstancebuildConfiguration reload 基于incubar…...
【Java SE】接口类型
在 Java 中,接口(Interface)是一种引用类型,类似于特殊的抽象类,用于定义一组方法规范,而不提供具体的实现。接口可以包含成员属性,这些属性默认是常量。尽管每个类只能继承一个父类,…...
[代码随想录Day10打卡] 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
理论基础 队列先入先出。 栈先入后出。 具体的实现和用法根据语言的不同而不同。 参考的文章 https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 232.用栈实现队列 这个定义入栈和出栈,往队列中加入…...
redis:RDB和AOF机制
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言RDBAOF总结 前言 redis是一个内存数据库,把数据存储在内存中的,而内存中的数据是不持久的,要想能够做…...
券商隔夜单自动下单交易接口
之前研究打板排板,研究怎么才能买得进去。 最近遇到几只利空跌停板,缩量跌停,明天大概率继续一字封板跌停。 如果卖不掉,意味着还要继续吃几个跌停,甚至ST票十几个跌停都有可能。 一次跌停亏几万,还是挺…...
生成任意3D和4D场景!GenXD:通用3D-4D联合生成框架 | 新加坡国立微软
文章链接: https://arxiv.org/pdf/2411.02319 项目链接:https://gen-x-d.github.io/ 有视频 亮点直击 设计了一个数据整理流程,从视频中获取包含可移动物体的高质量4D数据,并为30,000个视频标注了相机姿态。这个大规模数据集称为CamVid-30K&…...
通过命令学习k8s
1、kubectl 命令可以列出所有命令 2、kubectl version 命令可以查看版本号 3、kubectl cluster-info命令可以查看集群信息(192.168.218.136:6443 即为kube-apiserver的IP和端口。) [rootk8s-master ~]# kubectl cluster-info Kubernetes master is run…...
【redis】—— 初识redis(redis基本特征、应用场景、以及重大版本说明)
序言 本文将引导读者探索Redis的世界,深入了解其发展历程、丰富特性、常见应用场景、使用技巧等,最后会对Redis演进过程中具有里程碑意义的版本进行详细解读。 (一)初始redis Redis是一种基于键值对(key-value&#x…...
服务器显卡和桌面pc显卡有什么不同
服务器显卡和桌面 PC 显卡在设计目标、性能优化、功能支持和硬件规格上都有显著不同。以下是主要区别: 1. 设计用途 服务器显卡:主要用于计算、深度学习、数据分析、科学计算、虚拟化和图形渲染等任务。其设计目标是持续高负载计算,保证高稳…...
Chrome使用IE内核
Chrome使用IE内核 1.下载扩展程序IE Tab 2.将下载好的IE Tab扩展程序拖拽到扩展程序界面,之后重启chrome浏览器即可...
类和对象(C++)——默认成员函数,构造函数,析构函数
1. 类的默认成员函数 默认成员函数就是用户没有显式实现,编译器会⾃动⽣成的成员函数称为默认成员函数。⼀个类,不写的情况下编译器会默认生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载&#…...
深入理解 Vue v-model 原理与应用
一、引言 在 Vue.js 开发中,v-model是一个非常重要且强大的指令。它为开发者在处理表单输入和数据双向绑定等场景中提供了极大的便利。无论是新手还是有经验的开发者,深入理解v-model对于高效地构建 Vue 应用至关重要。本文将对v-model进行深入剖析,从其基本原理、使用方式…...
内网域环境、工作组、局域网等探针方案
1. 信息收集 1.1 网络收集 了解当前服务器的计算机基本信息,为后续判断服务器角色,网络环境做准备 systeminfo 详细信息 net start 启动服务 tasklist 进程列表 schtasks 计划任务(受权限影响) 了解当前服务器的网络接口信息…...
uniapp—android原生插件开发(3Android真机调试)
本篇文章从实战角度出发,将UniApp集成新大陆PDA设备RFID的全过程分为四部曲,涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程,轻松应对安卓原生插件开发与打包需求! 一、打包uniapp资源包: 打包…...
goframe开发一个企业网站 统一返回响应码 18
响应码的logic package returncodeimport ("context""gf_new_web/internal/service""github.com/gogf/gf/v2/errors/gcode""github.com/gogf/gf/v2/frame/g" )type sReturncode struct { }var (insReturncode sReturncode{}…...
基于STM32的智能门禁系统设计
引言 本项目基于STM32微控制器设计了一个智能门禁系统,通过集成多个传感器模块和控制设备,实现对门禁系统的自动化管理与控制。该系统能够通过RFID卡、密码输入、以及指纹传感器等多种方式对进出人员进行验证,并结合LCD显示屏提供实时信息反…...
Python学习从0到1 day28 Python 高阶技巧 ⑧ 递归
那就祝我们爬不同的山,还能回到同一条路上,不是时时见面,但是时时惦记之人 —— 24.11.13 递归 1.什么是递归 递归在编程中是一种非常重要的算法 递归:即方法(函数)自己调用自己的一种特殊编程写法 函数调用自己,即…...
知识见闻 - 苹果手机拨号键长按
苹果手机(iPhone)在拨号界面长按按键时有一些特定的功能。以下是iPhone拨号键盘上长按按键的主要功能: 数字键 0 - 长按可输入""号,用于国际电话拨号 - 这是最常用的长按功能之一,方便用户拨打国际电话 星号…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
