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 - 长按可输入""号,用于国际电话拨号 - 这是最常用的长按功能之一,方便用户拨打国际电话 星号…...

在 KubeVirt 中使用 GPU Operator
在 KubeVirt 中使用 GPU Operator 基于最新的GPU Operator版本24.9.0。 原文链接:GPU Operator with KubeVirt — NVIDIA GPU Operator 24.9.0 documentation 1. 简介 KubeVirt 是 Kubernetes 的一个虚拟机管理插件,允许您在 Kubernetes 集群中运行和…...

安慰剂检验Stata代码(全套代码、示例数据及参考文献)
数据简介:随着因果推断方法在实证研究中的使用比例不断提升,越来越多的文章进行安慰剂检验。其检验基本原理与医学中的安慰剂类似,即使用假的政策发生时间或实验组进行分析,以检验能否得到政策效应。如果依然得到了政策效应&#…...

DAY6 线程
作业1: 多线程实现文件拷贝,线程1拷贝一半,线程2拷贝另一半,主线程回收子线程资源。 代码: #include <myhead.h> sem_t sem1; void *copy1()//子线程1函数 拷贝前一半内容 {int fd1open("./1.txt",O…...

基于STM32的智能门锁系统设计思路:蓝牙、RFID等技术
一、项目概述 在现代家居安全领域,传统门锁因其安全性不足、开锁方式单一等问题,已逐渐无法满足用户的需求。传统机械锁容易被撬开、复制钥匙,同时开锁方式仅限于物理钥匙,给用户带来不便。因此,本文旨在设计并开发一…...

AndroidStudio-广播
一、广播的本质 广播是一种数据传输方式 二、Android 中的广播 发送一条广播,可以被不同的广播接收者所接收,广播接收者收到广播之后,再进行逻辑处理。 三、收发标准广播 广播的收发过程分为三个步骤: 1.发送标准广播 2.定义…...

基于表格滚动截屏(表格全部展开,没有滚动条)
import html2canvasPro from html2canvas // 截图,平辅表格 async function resetAgSize() {const allColumns gridApi.value.getColumns()let totalColumnWidth 0let totalColumnHeight 0// 遍历每一个行节点gridApi.value.forEachNode((rowNode) > {totalCo…...

洛谷P1255
P1255 数楼梯 - 洛谷 | 计算机科学教育新生态 数楼梯 题目描述 楼梯有 N 阶,上楼可以一步上一阶,也可以一步上二阶。 编一个程序,计算共有多少种不同的走法。 输入格式 一个数字,楼梯数。 输出格式 输出走的方式总数。 样…...

vue3设置第三方组件 样式::v-deep
在Vue 3中,使用了Composition API的组件可以通过<style>标签内部的::v-deep选择器来深入作用于第三方组件的样式。::v-deep是一个 Scoped CSS 的“深度选择器”,可以穿透组件边界,影响子组件的样式。比如我想修改el-date-picker的颜色边…...

JAVA学习日记(十四)集合进阶
一、单列集合Collection List系列集合特点:添加的元素是有序(存和取的顺序一致)、可重复、有索引 Set系列集合特点:添加的元素是无序(存和取的顺序有可能不一致)、不重复、无索引 Collection是所有单列集合…...

mysql全量与增量备份
binlog日志: 从上一次全量备份到下一次全量备份直接产生的数据。 一、全备和增量备份介绍 1、全量备份: 备份所有数据库或只备份一个数据库,全量备份之后,全量备份之前的binlog日志就没用了,一般生产环境会保留3-7天…...