【C语言】文件操作详解
文章目录
- 前言
- 一、文件是什么
- 二、文件具体介绍
- 1.文件名
- 2.文件类型
- 3.文件缓冲区
- 4.文件指针
- 5.文件的打开和关闭
- 三、文件的顺序读写
- 1.字符输入函数(fgetc)
- 2.字符输出函数(fputc)
- 3.文本行输入函数(fgets)
- 4.文本行输出函数(fputs)
- 5.二进制输入(fread)
- 6.二进制输出(fwrite)
- 四、文件随机读写
- 1.fseek
- 2.ftell
- 3.rewind
- 总结
添加链接描述
前言
大家好呀,今天小小樊为大家分享一下自己对于C语言中文件操作学习的理解,希望可以帮助到大家!!!
`
一、文件是什么
磁盘上的文件是文件。
但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件
程序文件
包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
本篇讨论的是数据文件。
二、文件具体介绍
1.文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如: c:\code\test.txt
为了方便起见,文件标识常被称为文件名。
2.文件类型
根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节
#include <stdio.h>
int main()
{
int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
fclose(pf);
pf = NULL;
return 0;
}
3.文件缓冲区
系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐
个地将数据送到程序数据区(程序变量等)。
我们可以对缓冲区的存在进行验证:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<windows.h>int main()
{char arr[20] = "zhangjiawang";FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen:");return 1;}fputs(arr,pf);//数据放在了输出缓冲区上Sleep(10000);//睡眠10秒fflush(pf);//刷新缓冲区,才能将输出缓冲区的数据写到文件上Sleep(10000);//睡眠10秒在看fclose(pf);//关闭文件,也会刷新缓冲区pf = NULL;return 0;
}
这个时候还未写入文件
这个时候就写入文件了!!
4.文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及
文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建一个FILE*的指针变量:
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文
件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
5.文件的打开和关闭
FILE * fopen ( const char * filename, const char * mode );//打开文件的函数,第一个参数文件名,第二个参数打开方式int fclose ( FILE * stream );//关闭文件的函数,参数接收文件信息区的起始地址
打开方式:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{FILE* fp = fopen("1.txt", "r");//打开该文件的话,就会将该文件的文件信息区的首地址传给文件指针FILE*fp,打不开返回空地址,表明错误if (fp == NULL){perror("fopen:");//打印错误return 1;//异常退出}fclose(fp);//关闭文件fp = NULL;//文件指针置为空指针,防止出现野指针
}
当打开文件时,该文件并没有创建,用读“r’‘的方式去打开文件时,不会存在对应文件的文件信息区,则不会返回对应文件信息区的地址,返回一个空指针,打印错误原因
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{FILE* fp = fopen("1.txt", "w");if (fp == NULL){perror("fopen:");return 1;}fclose(fp);fp = NULL;
}
当以"w"方式打开文件,如果没有该文件会重新创建一个该文件
三、文件的顺序读写
1.字符输入函数(fgetc)
函数声明:int fgetc( FILE *stream );
参数:要读取的文件的文件指针变量
返回值:读取成功返回读取到的字符,读取到文件末尾或读取失败则返回EOF,EOF是个负数,这也是为什么用返回值类型为int,而不是char
从文件中读到字符变量中
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "r");if (fp == NULL){perror("fopen");return 1;}char ch=fgetc(fp);printf("%c", ch);fclose(fp);fp = NULL;
}
一次只能读一个字符
要想使用fgetc全读出paopao
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "r");if (fp == NULL){perror("fopen");return 1;}char ch;while ((ch = fgetc(fp)) != EOF)//没到文件结尾,循环读字符{printf("%c", ch);}fclose(fp);fp = NULL;
}
注意:你要读文件必须先存在文件,并且有内容才能读到,打开文件方式“r"
2.字符输出函数(fputc)
函数声明:int fputc(int char, FILE *stream)
参数:char 要被写入的字符。该字符以其对应的 int 值进行传递。 stream – 这是指向 FILE 对象的指针,接收文件信息区的地址,该 FILE对象(对应的文件信息区)标识了要被写入字符的流。
返回值:如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "w");if (fp == NULL){perror("fopen");return 1;}fputc('a', fp);fputc('a', fp);fputc('a', fp);fclose(fp);fp = NULL;
}
注意:同一个文件再次写入时,用“w"打开文件,文件之前内容被覆盖
3.文本行输入函数(fgets)
函数声明:char *fgets(char *s, int size, FILE *stream);
参数:s接收的时从文件中读到字符串数组的地址,size是从文件中一次读几个字符,stream接收对应文件信息区地址
返回值:成功返回字符串,错误或文件结束条件返回NULL。
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "r");if (fp == NULL){perror("fopen");return 1;}char arr[256];//定义字符数组fgets(arr,10,fp);//从文件读取字符到数组printf("%s", arr);//打印字符数组fclose(fp);fp = NULL;
}
注意:最后会读一个‘\0’给字符数组
4.文本行输出函数(fputs)
函数声明:int fputs(const char *s, FILE *stream);
参数: s 代表要输出的字符串的首地址,stream接收文件信息区的地址
返回值:该函数返回一个非负值,如果发生错误则返回 EOF。
int main()
{FILE* fp = fopen("2.txt", "w");if (fp == NULL){perror("fopen");return 1;}char arr[256]="abc";fputs(arr,fp);//printf("%s", arr);fclose(fp);fp = NULL;
}
也可以直接传字符串,也相当于接收字符串起始地址
5.二进制输入(fread)
函数声明:size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
参数:参数1:文件读到内存的位置.参数2:读到基本单元字节大小.参数3:读到基本单元字节个数4:文件指针 ;
返回值:返回读取或回写的记录数,数据项的个数,fread是一个函数。从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功或读到文件末尾返回 0。
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "rb");if (fp == NULL){perror("fopen");return 1;}char arr[256] = {0};int sz=sizeof(arr);while (!feof(fp))//使用 feof(fp) 判定文件是否读取完毕 , 如果返回 1 说明文件没有读取完毕 , 返回 0 , 说明文件读取完毕{fread(arr, 1, sz-1, fp);//为了避免乱码出现,参数3传入字符串长度大小-1,不会出现乱码}printf("%s", arr);fclose(fp);fp = NULL;
}
6.二进制输出(fwrite)
函数声明:size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
参数:参数1:文件从内存读取数据的位置.参数2:读到基本单元字节大小.参数3:读到基本单元字节个数4:文件指针 ;
返回值: size_t 返回值返回的是实际写出到文件的 基本单元 个数 。
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "wb");if (fp == NULL){perror("fopen");return 1;}char arr[] = "yuebanxiaoyequ";int sz=sizeof(arr);fwrite(arr,1, sz-1, fp);fclose(fp);fp = NULL;
}
四、文件随机读写
1.fseek
根据文件指针的位置和偏移量来定位文件指针。
函数声明:int fseek ( FILE * stream, long int offset, int origin );
参数:stream文件指针。offset偏移量参数,为正向文件结尾偏移,为负向文件开头偏移,origin为开始偏移的位置,有3种取值
文件头 SEEK_SET
当前位置 SEEK_CUR
文件尾 SEEK_END
2.ftell
返回文件指针相对于起始位置的偏移量
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "rb");if (fp == NULL){perror("fopen");return 1;}char arr[256] = { 0 };int sz = sizeof(arr);fseek(fp,6,SEEK_SET);int num = ftell(fp);//num的返回值应该是偏移量6printf("%d ", num);while (!feof(fp))//使用 feof(fp) 判定文件是否读取完毕 , 如果返回 1 说明文件没有读取完毕 , 返回 0 , 说明文件读取完毕{fread(arr, 1, sz - 1, fp);//为了避免乱码出现,参数3传入字符串长度大小-1,不会出现乱码}printf("%s", arr);fclose(fp);fp = NULL;
}
3.rewind
让文件指针的位置回到文件的起始位置
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{FILE* fp = fopen("2.txt", "rb");if (fp == NULL){perror("fopen");return 1;}char arr[256] = { 0 };int sz = sizeof(arr);fseek(fp,6,SEEK_SET);rewind(fp);//回到原点int num = ftell(fp);//num此时为0,并且打印文件中所有信息printf("%d ", num);while (!feof(fp))//使用 feof(fp) 判定文件是否读取完毕 , 如果返回 1 说明文件没有读取完毕 , 返回 0 , 说明文件读取完毕{fread(arr, 1, sz - 1, fp);//为了避免乱码出现,参数3传入字符串长度大小-1,不会出现乱码}printf("%s", arr);fclose(fp);fp = NULL;
}
总结
文件操作中常用的知识就是这些啦,这些就是博主的全部理解啦,希望能够帮助到各位读者,如有不正确的地方,还请大家指正,谢谢大家!!!
相关文章:

【C语言】文件操作详解
文章目录 前言一、文件是什么二、文件具体介绍1.文件名2.文件类型3.文件缓冲区4.文件指针5.文件的打开和关闭 三、文件的顺序读写1.字符输入函数(fgetc)2.字符输出函数(fputc)3.文本行输入函数(fgets)4.文本…...

栈(Stack)的详解
目录 1.栈的概念 2.栈的模拟实现 1.栈的方法 2.模拟栈用(整型)数组的形式呈现 2.1栈的创建 2.2压栈 2.3栈是否为空 2.4出栈 2.5获取栈中有效元素个数 2.6获取栈顶元素 2.7完整代码实现 1.栈的概念 从上图中可以看到, Stack 继承了…...

深入了解GCC编译过程
关于Linux的编译过程,其实只需要使用gcc这个功能,gcc并非一个编译器,是一个驱动程序。其编译过程也很熟悉:预处理–编译–汇编–链接。在接触底层开发甚至操作系统开发时,我们都需要了解这么一个知识点,如何…...

leetcode 594.最长和谐子序列(滑动窗口)
⭐️ 题目描述 🌟 leetcode链接:最长和谐子序列 思路: 第一步先将数组排序,在使用滑动窗口(同向双指针),定义 left right 下标,比如这一组数 {1,3,2,2,5,2,3,7} 排序后 {1,2,2,2,3,…...
深入剖析云计算与云服务器ECS:从基础到实践
云计算已经在不断改变着我们的计算方式和业务模式,而云服务器ECS(Elastic Compute Service)作为云计算的核心组件之一,为我们提供了灵活、可扩展的计算资源。在本篇长文中,我们将从基础开始,深入探讨云计算…...

苍穹外卖技术栈
重难点详解 1、定义全局异常 2、ThreadLocal ThreadLocal 并不是一个Thread,而是Thread的一个局部变量ThreadLocal 为每一个线程提供独立的存储空间,具有线程隔离的效果,只有在线程内才能取到值,线程外则不能访问 public void …...
重新开始 杂类:C++基础
目录 1.输入输出 2 . i 与 i 3.结构体 4.二进制 1.输入输出 #include<cstdio>//cin>>,cout #include<iostream>//printf,scanf (1) cin , cout输入输出流可直接用于数字,字符 (2)scanf(&quo…...
自用的markdown与latex特殊符号
\triangleq \approx \xlongequal[y\arctan x]{x\tan y} \sum_{\substack{j1 \\ j\neq i}} \iiint\limits_\Omega \overset{\circ}{\vec{r}} \varphi \checkmark \stackrel{\cdot\cdot\cdot}{x}≜ ≈ y arctan x x tan y ∑ j 1 j ≠ i ∭ Ω r ⃗ ∘ φ ✓ x ⋅ ⋅ ⋅…...

【20期】说一说Java引用类型原理
Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用、软引用、弱引用、虚引用。 其中强引用就是我们经常使用的Object a new Object(); 这样的形式,在Java中并没有对应的Reference类。 本篇文章主要是分析软引用、弱引用、…...

无锡布里渊——厘米级分布式光纤-锅炉安全监测解决方案
无锡布里渊——厘米级分布式光纤-锅炉安全监测解决方案 厘米级分布式光纤-锅炉安全监测解决方案 1、方案背景与产品简介: 1.1:背景简介: 锅炉作为一种把煤、石油或天燃气等化石燃料所储藏的化学能转换成水或水蒸气的热能的重要设备ÿ…...
GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING
本文是LLM系列文章,针对《GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING》的翻译。 GREASELM:图推理增强的问答语言模型 摘要1 引言2 相关工作3 提出的方法:GREASELM4 实验设置5 实验结果6 结论 摘要 回答关…...

QT C++ 实现网络聊天室
一、基本原理及流程 1)知识回顾(C语言中的TCP流程) 2)QT中的服务器端/客户端的操作流程 二、代码实现 1)服务器 .ui .pro 在pro文件中添加network库 .h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>…...
每日一道面试题之什么是上下文切换?
上下文切换是指在计算机操作系统中,当多个进程或线程同时运行时,系统需要将当前运行进程或线程的状态(包括程序计数器、寄存器值、内存映像等)保存起来,然后切换到另一个进程或线程继续执行的过程。上下文切换通常由操…...

2023.9.3 关于 AVL 树
目录 二叉搜索树 二叉搜索树的简介: 二叉搜索树的查找: 二叉搜索树的效率: AVL树 AVL 树的简介: AVL 树的实现: AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 完整 AVL树插入代码 验证 AVL 树 AVL 树的性…...
机器学习课后习题 --- 机器学习实践
(一)单选题 1.以下关于训练集、验证集和测试集说法不正确的是( )。 A:测试集是纯粹是用于测试模型泛化能力B:训练集是用来训练以及评估模型性能 C:验证集用于调整模型参数 D:以上说法都不对 2.当数据分布不平衡时,我们可采取的措施不包括…...
git常用操作
删除分支 例:例如想删除的分支是dev_delete,那么可以按照如下的操作进行 #查看当前所在分支 git branch#如果在当前dev_delete分支上,就要切换到其他分支才能删除该分支 git checkout 其他分支#删除本地名为dev_delete的分支 git branch -d dev_delete…...
QT的补充知识
一、文件 QFile QT提供了QFile类用于对文件进行读写操作,也提供了其他的两个类:文本流(QTextSream)和数据流(QDataStream) 文本流(QTextSream):用于对文本数据的处理&am…...

【力扣周赛】第 360 场周赛(贪心 ⭐树上倍增)
文章目录 竞赛链接Q1:8015. 距离原点最远的点(贪心)Q2:8022. 找出美丽数组的最小和(贪心)Q3:2835. 使子序列的和等于目标的最少操作次数(贪心)思路竞赛时丑陋代码&#x…...

企业如何防止数据外泄——【部署智能透明加密防泄密系统】
为防止公司文件泄密,可以采取以下措施: www.drhchina.com 分部门部署:根据不同的部门需要,为不同部门用户部署灵活的加密方案。例如,对研发部、销售部、运营部的机密资料进行强制性自动加密,对普通部门的文…...

【聚类】DBCAN聚类
OPTICS是基于DBSCAN改进的一种密度聚类算法,对参数不敏感。当需要用到基于密度的聚类算法时,可以作为DBSCAN的一种替代的优化方案,以实现更优的效果。 原理 基于密度的聚类算法(1)——DBSCAN详解_dbscan聚类_root-ca…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...

Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...