C语言【文件】

目录

 概念

 文件名

 文件的打开和关闭

fopen

fclose 

输入输出函数 

 fputc

fgetc

fputs

fgets 

fprintf

fscanf

fwrite

fread

三种流

scanf和sprintf

 结构体转化

​编辑

 文件的随机读写

fseek

ftell

rewind

文本文件和二进制文件

文件读取结束的判定

文件缓冲区


 概念

文件的作用:文件是存放于硬盘中的,使数据能够持久化保存。

数据文件文件的内容不一定是程序,它可以是程序运行时产生的读写数据。

有时后我们会将文件输出到磁盘上,在需要的时候再从磁盘上把数据读取到内存中使用。

 文件名

一个文件需要一个唯一的文件标识:
文件路径 + 文件名主干 + 文件后缀

例: c:\code\test.txt

 文件的打开和关闭
 

为了方便访问文件中的数据,每个被使用的文件都在内存中开辟了一个相应的文件信息区,记录文件名文件的状态、文件路径等)。这个文件信息区被存放在一个结构体变量中,通过文件指针可以访问这块区域,并对文件实施各种操作。

FILE* pf;//文件指针变量

 

fopen

根据文件名打开打开文件,并返回一个FILE*类型的指针。

文件操作模式类型(第二个参数): 

注意文件路径可以是相对或绝对路径
 

fclose 

关闭文件,和fopen一起使用。 

输入输出函数 

 fputc

意为将字符写入到文件中。

返回值: 为字符的ASCII码值(非负值)。失败返回-1。

 利用返回值写入的数据依次打印到屏幕上:

int main()
{//打开文件FILE* pf = fopen("text.txt", "w");if (NULL == pf){perror("fopen");return 1;}//写文件int i = 0;for (i = 0; i < 26; i++){putchar(fputc('a'+i, pf));}fclose(pf);pf = NULL;return 0;
}

fgetc

意为获取文件中的字符返回它的ascii码在使用fgetc前,要确保文件状态为 r 专注输入数据而非w专注输出数据,否则会导致读取失败。

 pf指针具有Placeholder指针可以遍历文件:

 

int main()
{//打开文件FILE* pf = fopen("text.txt", "r");if (NULL == pf){perror("fopen");return 1;}
int ch = 0;while ((ch = fgetc(pf)) != EOF)//意为读取文件所有内容之后返回-1(文件末尾){printf("%c", ch);}fclose(pf);pf = NULL;return 0;
}

fputs

作用:将字符串写入到文件中,想达到按行写入可以主动加上\n

返回值:成功时返回非负值,失败返回-1。

 

fgets 

作用:从文件中依次读取字符串,遇到\n或者读取(num-1)个数字后终止读取。也就是说它只读取num-1个数字并在num或\n后处自动补上\0

返回值:str的首地址,若失败返回NULL。

  

fprintf

 从文件流中按照一定格式写数据。

 例如复杂的结构体

struct S
{char name[20];int age;float score;
};


fscanf

 从文件流中按照一定格式读数据。

 

当然,你也可以用前面的文件读取函数进行读取:

char arr[20] = { 0 };
fgets(arr,20,pf);//也行
printf("%s",arr);

fwrite

对文件进行二进制写入。[适用于所有类型]

第一个参数为写入数据的地址,第二个参数为数据的大小,第三个参数为数据个数。类似于memcpy一个字节一个字节拷贝数据。

 注意读写二进制文件属性要变为 ”wb"

 

这下知道文件中为什么会有乱码了吧~ 

fread

对文件进行二进制读取,会返回读取成功的count个数。

 

三种流

而文件输入输出函数适用于所有流它们对数据的操作可以不局限于文件。也就是说可以用它们实现像scanf、printf之类函数的功能:

fprintf(stdout, "hello world");//屏幕
int a = 0;
fscanf(stdin,"%d" ,a);//键盘

scanf和sprintf

sscanf按照一定格式将字符串转换为特定格式

sprintf将其他数据类型按照指定的格式转换成字符串。【后面自动补‘\0’】

 结构体转化

将结构体转化成字符串:

 将字符串转化成结构体:

 文件的随机读写

fseek

作用:将流里文件指针设置起始位置偏移量,按此偏移量的位置进行读写操作。

 

SEEK_END为末尾数据的下一个位置 

	int ch = fgetc(pf);putchar(ch);
//afseek(pf,-2,SEEK_END);//反向找ch = fgetc(pf);putchar(ch);
//efseek(pf, 0, SEEK_SET);//回到起始位置ch = fgetc(pf);putchar(ch);
//a//查找完a后指针位置会向后增1fseek(pf, 3, SEEK_CUR);//b-->cdech = fgetc(pf);putchar(ch);
//e

ftell

返回当前文件指针所指向的位置(偏移量)。

rewind

 将文件指针设置成最开始的位置。

文本文件和二进制文件

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是 二进制文件 。(乱码)
字符一律以 ASCII 形式存储,数值型数据既可以用 ASCII 形式存储,也可以使用二进制形式存储。

对于整数10000,以ASCII码存储为5个字节,而二进制存储只占4和字节。

文件读取结束的判定

牢记:在文件读取过程中,不能用 feof 函数的返回值直接用来判断文件的是否结束。
而是 应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
  • fgetc 判断是否为 EOF .
  • fgets 判断返回值是否为 NULL .
  • fread判断返回值是否小于实际要读的个数。

fgetc: 

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) { putchar(c);}if (ferror(fp))puts("I/O error when reading");else if (feof(fp))puts("End of file reached successfully");fclose(fp);
}

 二进制:

#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{double a[SIZE] = {1.,2.,3.,4.,5.};FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组fclose(fp);double b[SIZE];fp = fopen("test.bin","rb");size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组if(ret_code == SIZE) {puts("Array read successfully, contents: ");for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]);putchar('\n');} else {if (feof(fp))printf("Error reading test.bin: unexpected end of file\n");else if (ferror(fp)) {perror("Error reading test.bin");}}fclose(fp);
}

文件缓冲区

所谓文件缓冲区,就是在使用文件时,系统会为每个文件分配一块缓冲区用于存放数据,当内存向磁盘中传输数据或当磁盘向内存中传输数据的时候,这些数据会一个一个被加载到缓存区上,再一齐被加载到内存或磁盘上。

 

作用:将缓存区中的数据输出到流里(stdout、FILE) 

#include <windows.h>
#include <stdio.h>
int main()
{FILE* pf = fopen("text.txt", "w");if (NULL == pf){perror("fopen");return 1;}int a = 10000;fwrite(&a, sizeof(int), 1, pf);//二进制printf("内容存放在缓冲区,此时打开文件无内容\n");Sleep(10000);//休眠10秒,数据已经在缓存区上了fflush(pf);//刷新缓冲区printf("再打开文件,内容已存在\n");fclose(pf);//注:fclose在关闭文件的时候,也会刷新缓冲区pf = NULL;
}

注:读取写入数据时遇到\n或fclose也会刷新缓冲区。 

所以在我们对文件进行操作时别忘了执行刷新缓冲区文件关闭操作!否则可能造成文件读写出错。

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

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

相关文章

C++标准模板(STL)- 类型支持 (运行时类型识别,type_info )

运行时类型识别 定义于头文件 <typeinfo> 含有某个类型的信息&#xff0c;由实现生成。​​这是 typeid 运算符所返回的类。 std::type_info 定义于头文件 <typeinfo> class type_info; 类 type_info 保有一个类型的实现指定信息&#xff0c;包括类型的名称和…

【论文解读】Parameter-Efficient Transfer Learning for NLP

一. 介绍 1.1 为什么要引入Adapter 在存在许多下游任务的情况下&#xff0c;微调的参数效率很低:每个任务都需要一个全新的模型。作为替代方案&#xff0c;我们建议使用适配器模块进行传输。 1.2 论文目标 目标是建立一个在所有这些方面都表现良好的系统&#xff0c;但不需…

docker图形胡界面管理工具--Portainer可视化面板安装

1.安装运行Portainer docker run -d -p 8088:9000 \ > --restartalways -v /var/run/docker.sock:/var/run/docker.sock --privilegedtrue portainer/portainer--restartalways&#xff1a;Docker启动后容器自动启动 -p&#xff1a;端口映射 -v&#xff1a;路径映射2.通过…

写一个简单的解释器(2) 构建标记流

确定标记类型 分为几个大类&#xff1a; 用户符号&#xff08;类型/标识符/数字/字符串…)关键字 (流程控制和定义符)括号 &#xff08;这里暂时认为 [] 属于括号&#xff09;分号 上述四类标记基本囊括了 vc \texttt{vc} vc 中的所有最小单元的类型&#xff0c;但是因为构…

【C++】哈希应用——海量数据面试题

哈希应用——海量数据面试题 一、位图应用1、给定100亿个整数&#xff0c;设计算法找到只出现一次的整数&#xff1f;2、给两个文件&#xff0c;分别有100亿个整数&#xff0c;我们只有1G内存&#xff0c;如何找到两个文件交集&#xff1f;&#xff08;1&#xff09;用一个位图…

JAVA基础(JAVA SE)学习笔记(七)面向对象编程(进阶)

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 第二阶段&#xff1a;Java面向对象编程 6.面向对象编程&#xff08;基础&#xff09; 7.面向对象编程&…

Ubuntu下 u2net tensorrt模型部署

TensorRT系列之 Windows10下yolov8 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov8 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov7 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov6 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov5 tensorrt模型加速…

nginx部署vue项目(访问路径加前缀)

nginx部署vue项目(访问路径加前缀) nginx部署vue项目&#xff0c;访问路径加前缀分为两部分&#xff1a; &#xff08;1&#xff09;修改vue项目&#xff1b; &#xff08;2&#xff09;修改nginx配置&#xff1b; vue项目修改 需注意&#xff0c;我这是vue-cli3配置&#x…

某验四代滑块验证码逆向分析

逆向目标 目标&#xff1a;某验四代滑块验证码&#xff0c;w 参数逆向主页&#xff1a;aHR0cHM6Ly9ndDQuZ2VldGVzdC5jb20v加密算法&#xff1a;RSA、AES 通讯流程 验证码流程分析 进入网页后&#xff0c;打开开发者人员工具进行抓包&#xff0c;点击滑动拼图验证&#xff0c…

Vue3语法-双向绑定

点击加入精英计划可以加入 点击名字可以删除 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!-- vue.js --><script src"https://unpkg.com/vue3/dist/vue.glob…

微软正式发布开源应用平台 Radius平台

“ 10 月 18 日&#xff0c;微软 Azure 孵化团队正式发布开源应用平台 Radius&#xff0c;该平台将应用程序置于每个开发阶段的中心&#xff0c;重新定义应用程序的构建、管理与理解方式。” 简单的概括就是&#xff0c;它和Kubernetes不一样&#xff0c;Radius将应用程序放在每…

在Windows下Edge浏览器OA发起流程问题

在Edge浏览器中发起流程 如上图所示&#xff0c;不能正常打开Excel&#xff0c;自动将Excel表格转为了PDF 怎么处理&#xff1f;还得使用IE浏览器来访问&#xff0c;但打开IE后又自动跳转到Edge&#xff0c;根本就不给使用&#xff0c;在Edge下使用IE模式也解决不了这个问题。…

项目管理实战总结(二)-沟通路径

在一个大型的项目管理中&#xff0c;不同的沟通路径&#xff0c;会对整个事情的进展形成不同的影响。从项目管理的视角来看&#xff0c;该如何驱动项目有效进展&#xff0c;失之毫厘谬以千里。 沟通路径&#xff1a;调查问卷的推动事宜 在项目进行到了后期&#xff0c;甲方希…

python学习笔记7-图的建立常用技巧

题目链接 题目中给了邻接链表&#xff0c;转为邻接矩阵初始化邻接矩阵 graph [[] for _ in range(n)]dfs() 的写法&#xff0c; 用visi避免重复访问&#xff0c;得到每个点所在的联通分量中点的个数 class Solution:def countPairs(self, n: int, edges: List[List[int]]) -…

JVM的几个面试重点

JVM的内存区域划分 JVM类加载机制 前言 Java程序最开始是一个 .java 的文件&#xff0c;JVM把它编译成 .closs 文件&#xff08;字节码文件&#xff09;&#xff0c;运行 Java 程序&#xff0c; JVM 就会读取 .class 文件&#xff0c;把文件内容读取到内存中&#xff0c;构造出…

YOLOv5:修改backbone为SPD-Conv

YOLOv5&#xff1a;修改backbone为SPD-Conv 前言前提条件相关介绍SPD-ConvYOLOv5修改backbone为SPD-Conv修改common.py修改yolo.py修改yolov5.yaml配置 参考 前言 记录在YOLOv5修改backbone操作&#xff0c;方便自己查阅。由于本人水平有限&#xff0c;难免出现错漏&#xff0c…

HammerDB的安装和使用(超详细)

目录 ​编辑 一、HammerDB的介绍 二、HammerDB的安装 1、下载hammerdb安装包 2、权限配置以及安装 3、查看安装目录 三、安装前的配置 1、启动监听 2、启动数据库 3、创建表空间 1.修改临时表空间 2…

【源码解析】Spring源码解读-bean的加载

Spring的整体流程其实就是通过配置 xml、注解将自定义bean类信息进行配置&#xff0c;然后通过BeanDefinitionReader读取配置信息&#xff0c;由Dom转换成xml解析成Docment。在通过加载的配置信息进行初始化Bean对象&#xff0c;然后在对象的前后进行处理&#xff0c;也就是不同…

Elesticsearch使用总结

写在前面 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是当前流行的企业级搜索引擎。设计用于[云计…

vue3 更换 elemnt-ui / element-plus 版本npm命令

1. 安装 / 更换 element-ui 版本 [ 在 后面指定想要安装的版本 ] //卸载当前版本 npm uninstall element-ui //安装指定版本 npm i element-ui2.4.8 -S --legacy-peer-deps 2. 安装 / 更换 element-plus 版本 [ 在 后面指定想要安装的版本 ] npm install element-plus2.3…