C进阶-语言文件操作
本章重点:
什么是文件
文件名
文件类型
文件缓冲区
文件指针
文件的打开和关闭文件的顺序读写文件的随机读写文件结束的判定
1. 什么是文件
磁盘上的文件是文件。
但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件
1.1 程序文件
包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
1.2 数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
1.3 文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。文件名包含3部分:文件路径+文件名主干+文件后缀
例如: c:\code\test.txt
为了方便起见,文件标识常被称为文件名。
2. 文件的打开和关闭
2.1 文件指针
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE. 例如,VS2008编译环境提供的 stdio.h头文件中有以下的文件类型申明:
struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;
};
typedef struct _iobuf FILE;
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关
心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建一个FILE*的指针变量:
FILE* pf;//文件指针变量
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文 件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
2.2 文件的打开与关闭

int main()
{//相对路径//绝对路径///Users/fan/Documents/c_study/c_test26/data.txt//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//读文件//关闭文件fclose(pf);pf = NULL;return 0;
}
3. 文件的顺序读写
3.1 顺序读写函数介绍

int main()
{//相对路径//绝对路径///Users/fan/Documents/c_study/c_test26/data.txt//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","w");if (pf == NULL){perror("fopen");return 1;}//读文件//写文件// fputc('a',pf);// fputc('b',pf);// fputc('c',pf);int i = 0;for (i = 0; i < 26; i++){fputc('a'+i,pf);}//关闭文件fclose(pf);pf = NULL;return 0;
}
int main()
{//相对路径//绝对路径///Users/fan/Documents/c_study/c_test26/data.txt//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//读文件int ch = fgetc(pf);printf("%c\n",ch); //ach = fgetc(pf);printf("%c\n",ch); //bch = fgetc(pf);printf("%c\n",ch); //cch = fgetc(pf);printf("%c\n",ch);//d//写文件// fputc('a',pf);// fputc('b',pf);// fputc('c',pf);// int i = 0;// for (i = 0; i < 26; i++)// {// fputc('a'+i,pf);// }//关闭文件fclose(pf);pf = NULL;return 0;
}
int main()
{//相对路径//绝对路径///Users/fan/Documents/c_study/c_test26/data.txt//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//读文件// int ch = fgetc(pf);// printf("%c\n",ch); //a// ch = fgetc(pf);// printf("%c\n",ch); //b// ch = fgetc(pf);// printf("%c\n",ch); //c// ch = fgetc(pf);// printf("%c\n",ch);//d//写文件// fputc('a',pf);// fputc('b',pf);// fputc('c',pf);// int i = 0;// for (i = 0; i < 26; i++)// {// fputc('a'+i,pf);// }// fputs("hello fan\n",pf);// fputs("hello fanfan\n",pf);//读文件 - 读一行char arr[10] = {0};fgets(arr,15,pf);printf("%s\n",arr);fgets(arr,15,pf);printf("%s\n",arr);//关闭文件fclose(pf);pf = NULL;return 0;
}
struct S
{int a;float s;
};int main()
{//相对路径//绝对路径///Users/fan/Documents/c_study/c_test26/data.txt//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//写文件//struct S s = {100,3.14f};//fprintf(pf,"%d %f",s.a,s.s);struct S s = {0};fscanf(pf,"%d %f",&(s.a),&(s.s));printf("%d %f",s.a,s.s);//关闭文件fclose(pf);pf = NULL;return 0;
}
struct S
{int a;float s;char str[10];
};int main()
{struct S s = {99, 6.18f, "bit"};//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","wb");if (pf == NULL){perror("fopen");return 1;}//写文件fwrite(&s,sizeof(struct S),1,pf);//关闭文件fclose(pf);pf = NULL;return 0;
}
int main()
{struct S s = {0};//打开文件FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","rb");if (pf == NULL){perror("fopen");return 1;}//读文件fread(&s,sizeof(struct S),1,pf);printf("%d %f %s\n",s.a,s.s,s.str);//关闭文件fclose(pf);pf = NULL;return 0;
}
4. 文件的随机读写
4.1 fseek
根据文件指针的位置和偏移量来定位文件指针。
int fseek ( FILE * stream, long int offset, int origin );
int main()
{FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//读文件//定位文件指针到fint ch = fgetc(pf);printf("%c\n",ch); //ach = fgetc(pf);printf("%c\n",ch); //bch = fgetc(pf);printf("%c\n",ch); //c ch = fgetc(pf);printf("%c\n",ch); //dfseek(pf,-3,SEEK_END);ch = fgetc(pf);printf("%c\n",ch);//关闭文件fclose(pf);pf = NULL;return 0;
}
4.2 ftell
返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
int main()
{FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//读文件//定位文件指针到fint ch = fgetc(pf);printf("%c\n",ch); //ach = fgetc(pf);printf("%c\n",ch); //bch = fgetc(pf);printf("%c\n",ch); //c ch = fgetc(pf);printf("%c\n",ch); //d// fseek(pf,-3,SEEK_END);// ch = fgetc(pf);// printf("%c\n",ch);int pos = ftell(pf);printf("%d\n",pos); //4//关闭文件fclose(pf);pf = NULL;return 0;
}
4.3 rewind
让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );
int main()
{FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pf == NULL){perror("fopen");return 1;}//读文件//定位文件指针到fint ch = fgetc(pf);printf("%c\n",ch); //ach = fgetc(pf);printf("%c\n",ch); //bch = fgetc(pf);printf("%c\n",ch); //c ch = fgetc(pf);printf("%c\n",ch); //d// fseek(pf,-3,SEEK_END);// ch = fgetc(pf);// printf("%c\n",ch);// int pos = ftell(pf);// printf("%d\n",pos); //4rewind(pf); //回到起始位置ch = fgetc(pf);printf("%c\n",ch); //a//关闭文件fclose(pf);pf = NULL;return 0;
}
5. 文本文件和二进制文件

6. 文件读取结束的判断
6.1 被错误使用的feof
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
1. 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)
例如:
fgetc判断是否为EOF.
fgets判断返回值是否为NULL.
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。
int main(void)
{int c; // 注意:int,非char,要求处理EOFFILE *fp = fopen("test.txt", "r");if (!fp){perror("File opening failed");return EXIT_FAILURE;}// fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环{putchar(c);}// 判断是什么原因结束的if (ferror(fp))puts("I/O error when reading");else if (feof(fp))puts("End of file reached successfully");fclose(fp);
}//拷贝文件
//拷贝data.txt文件,产生一个新文件data1.txtint main()
{FILE* pfRead = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");if (pfRead == NULL){perror("open file for read");return 1;}FILE* pfWrite = fopen("/Users/fan/Documents/c_study/c_test26/data2.txt","w");if (pfWrite == NULL){perror("open file for write");fclose(pfRead);pfRead = NULL;return 1;}//读写文件int ch = 0;while((ch = fgetc(pfRead)) != EOF){fputc(ch,pfWrite);}//关闭文件fclose(pfRead);pfRead = NULL;fclose(pfWrite);pfWrite = NULL;return 0;
}
7. 文件缓冲区


相关文章:
C进阶-语言文件操作
本章重点: 什么是文件 文件名 文件类型 文件缓冲区 文件指针 文件的打开和关闭文件的顺序读写文件的随机读写文件结束的判定 1. 什么是文件 磁盘上的文件是文件。 但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件 1.1 程序文件…...
17-spring aop调用过程概述
文章目录 1.源码2. debug过程1.源码 public class TestAop {public static void main(String[] args) throws Exception {saveGeneratedCGlibProxyFiles(System.getProperty("user.dir") + "/proxy");ApplicationContext ac = new ClassPathXmlApplicatio…...
微信小程序------框架
目录 视图层 WXML 数据绑定 列表渲染 条件渲染 模板 wsx事件 逻辑层 生命周期 跳转 视图层 WXML WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。 先在我们的项目中…...
Cross-Modal Joint Embedding with Diverse Semantics
计算两个嵌入之间的相似度得分,然后利用损失函数进行联合嵌入损失最小化优化并更新参数 辅助信息 作者未提供代码...
工具 | macOS 最简方式安装 adb 工具 | Mac
工具 | macOS 最简方式安装 adb 工具 | Mac 介绍 ADB(Android Debug Bridge)是 Android开发工具包(SDK)中的一项实用工具,用于与 Android 设备进行通信和调试。 在 macOS 操作系统上安装 ADB 环境可以帮助开发人员与…...
linux进阶(脚本编程/软件安装/进程进阶/系统相关)
一般市第二种,以bash进程执行 shelle脚本编程 env环境变量 set查看所有变量 read设置变量值 echo用于控制台输出 类似java中的sout declear/typeset声明类型 范例 test用于测试表达式 if/else case while for 函数 脚本示例 软件安装及进阶 fork函数(复制一个进程(开启一个进…...
谷歌云:下一代开发者和企业解决方案的强力竞争者
自从2018年Oracle前研发总裁Thomas Kurian加入谷歌云(Google Cloud)并出任谷歌云CEO以来,业界对于谷歌云的发展就十分好奇。而谷歌云的前任CEO Diane Greene曾是VMware的创始人之一,那么两任企业级技术和解决方案出身的CEO&#x…...
任务分配问题(回溯法)
算法设计 问题描述 有n(n≥1)个任务需要分配给n个人执行,每个任务只能分配给一个人,每个人只能执行一个任务。 第i个人执行第j个任务的成本是c[i][j](1≤i,j≤n)。求出总成本最小的分配方案 …...
华为OD 字符串消除(100分)【java】A卷+B卷
华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…...
索引背后的数据结构——B+树
为什么要使用B树? 可以进行数据查询的数据结构有二叉搜索树、哈希表等。对于前者来说,树的高度越高,进行查询比较的时候访问磁盘的次数就越多。而后者只有在数据等于key值的时候才能进行查询,不能进行模糊匹配。所以出现了B树来解…...
面试用-常用注解
Configuration 注意由ConfigurationClassPostProcessor来处理ConfigurationClassPostProcessor执行这个后置处理 ConfigurationClassParser.parse执行这个方法里面会解析很多注解。1、Component 对于Component也是一样递归调用parse方法,一层层解析…...
【c++】跟webrtc学std array 4: H264PacketBuffer 包缓存
H264PacketBuffer m98代码:H264PacketBuffer 类似于PacketBuffer ,但仅用于H264// The H264PacketBuffer does the same job as the PacketBuffer but for H264 // only. To make it fit in with surronding code the PacketBuffer input/output // classes are used. 因此,…...
Nodejs Web数据库应用演示实例
Nodejs Web应用基础演示实例 Web数据库应用 一、服务器端 var express require(express); var app express(); var mysql require(mysql);//设置静态资源目录public app.use(express.static(__dirname /public));//创建mysql数据库访问连接(数据库主机地址&a…...
Vue 中setup的特性
特性四:父传子组件传参【defineProps】: 父组件(传递数据):利用自定义属性传递数据。 <template><h3>我是父组件</h3><hr /><Child :name"info.name" :age"info.age"…...
Peter算法小课堂—正整数拆分
大家可能会想:正整数拆分谁不会啊,2年级就会了,为啥要学啊 例题 正整数拆分有好几种,这里我们列举两种讲。 关系 我们看着第一幅图,头向左转90,记住你看到的图,再来看第二幅图,你…...
EDUSRC--简单打穿某985之旅
免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…...
vue2升级到vue2.7
vue2升级到vue2.7 小小的改进,大大的提升 只需要简单修改,开发体验得到大大提升. 为什么要升级Vue2.7 不能拒绝的理由: 组合式 API(解决mixins问题:命名冲突,隐式依赖)单文件组件内的 <script setup>语法模板表达式中支持 ESNext 语法(可选链:?.、空值合并:??)单文…...
【django2.0之Rest_Framework框架一】rest_framework序列器介绍
Django RestFramework(简称DRF) 提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文…...
Mock 测试详解:什么是 Mock 测试
Mock测试 什么是 Mock ? Mock 的意思就是,当你很难拿到源数据时,你可以使用某些手段,去获取到跟源数据相似的假数据,拿着这些假数据,前端可以先行开发,而不需要等待后端给了数据后再开发。 Mo…...
Android端自定义铃声
随着移动应用竞争进入红海时代,如何在APP推送中别出心裁显得尤为重要。例如对自己的APP推送赋予独特的推送铃声,能够给用户更加理想的使用体验。 1、个性化提醒铃声有助于当收到特定类型的消息时,用户能够立刻识别出来。 2、不同的推送铃声…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
