考研C语言复习进阶(5)

目录

1. 为什么使用文件

2. 什么是文件

2.1 程序文件

2.2 数据文件

2.3 文件名

3. 文件的打开和关闭

3.1 文件指针

3.2 文件的打开和关闭

 4. 文件的顺序读写

​编辑

​编辑

 4.1 对比一组函数:

​编辑 5. 文件的随机读写

5.1 fseek

 5.2 ftell

5.3 rewind

6. 文本文件和二进制文件

 7. 文件读取结束的判定

7.1 被错误使用的feof

8. 文件缓冲区


1. 为什么使用文件

我们前面学习结构体时,写了通讯录的程序,当通讯录运行起来的时候,可以给通讯录中增加、删除数据,此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下次运行通讯录程序的时候,数据又得重新录入,如果使用这样的通讯录就很难受。
我们在想既然是通讯录就应该把信息记录下来,只有我们自己选择删除数据的时候,数据才不复存在。
这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。
使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

2. 什么是文件

磁盘上的文件是文件。
但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。

2.1 程序文件


包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境
后缀为.exe)。


2.2 数据文件


文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,
或者输出内容的文件。
本章讨论的是数据文件。
在以前各章所处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。

其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件。


2.3 文件名


一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如: c:\code\test.txt
为了方便起见,文件标识常被称为文件名。

3. 文件的打开和关闭


3.1 文件指针


缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.
例如,VS2013编译环境提供的 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指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
比如: 

 

3.2 文件的打开和关闭


文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。 

//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );

打开方式如下:

文件使用方式                 含义                                                                 如果指定文件不存在
“r”(只读) 为了输入数据,打开一个已经存在的文本文件                                 出错
“w”(只写) 为了输出数据,打开一个文本文件                                         建立一个新的文件
“a”(追加) 向文本文件尾添加数据                                                            建立一个新的文件
“rb”(只读) 为了输入数据,打开一个二进制文件                                             出错
“wb”(只写) 为了输出数据,打开一个二进制文件                                   建立一个新的文件
“ab”(追加) 向一个二进制文件尾添加数据                                                       出错
“r+”(读写) 为了读和写,打开一个文本文件                                                    出错
“w+”(读写) 为了读和写,建议一个新的文件                                         建立一个新的文件
“a+”(读写) 打开一个文件,在文件尾进行读写                                      建立一个新的文件
“rb+”(读写) 为了读和写打开一个二进制文件                                                  出错
“wb+”(读写) 为了读和写,新建一个新的二进制文件                           建立一个新的文件
“ab+”(读写) 打开一个二进制文件,在文件尾进行读和写                     建立一个新的文件

实例代码:

/* fopen fclose example */
#include <stdio.h>
int main ()
{FILE * pFile;//打开文件pFile = fopen ("myfile.txt","w");//文件操作if (pFile!=NULL)
{fputs ("fopen example",pFile);//关闭文件fclose (pFile);
}return 0;
}

 4. 文件的顺序读写

功能                                                 函数名                                                  适用于
字符输入函数                                   fgetc                                                 所有输入流
字符输出函数                                   fputc                                                 所有输出流
文本行输入函数                               fgets                                                 所有输入流
文本行输出函数                               fputs                                                 所有输出流
格式化输入函数                               fscanf                                               所有输入流
格式化输出函数                               fprintf                                                 所有输出流
二进制输入                                      fread                                                 文件
二进制输出                                      fwrite                                                 文件

 

 

 

 

fprintf和fscanf 后面的参数是可变参数列表。

 

 

 4.1 对比一组函数:


scanf/fscanf/sscanf
printf/fprintf/sprintf
这里演示讲解这句函数的使用和对比

sprintf和sscanf使用:

 5. 文件的随机读写


5.1 fseek


根据文件指针的位置和偏移量来定位文件指针。

 

例子:

SEEK_CUR是pf当前位置

SEEK_SET是pf起始位置 

 5.2 ftell


返回文件指针相对于起始位置的偏移量

 

5.3 rewind


让文件指针的位置回到文件的起始位置

 

6. 文本文件和二进制文件


根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试) 

小端存储:

#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;
}

 7. 文件读取结束的判定


7.1 被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
fgetc 判断是否为 EOF .
fgets 判断返回值是否为 NULL .
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。
正确的使用:
文本文件的例子:

#include <stdio.h>
#include <stdlib.h>
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);
}

二进制文件的例子

#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 { // error handlingif (feof(fp))printf("Error reading test.bin: unexpected end of file\n");else if (ferror(fp)) {perror("Error reading test.bin");}}fclose(fp);
}

8. 文件缓冲区


ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。 

 

#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
int main()
{
FILE*pf = fopen("test.txt", "w");
fputs("abcdef", pf);//先将代码放在输出缓冲区
printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
//注:fflush 在高版本的VS上不能使用了
printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在关闭文件的时候,也会刷新缓冲区
pf = NULL;
return 0;
}

这里可以得出一个结论:
因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果不做,可能导致读写文件的问题。

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

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

相关文章

【C语言】linux内核pci_save_state

一、中文注释 //include\linux\pci.h /* 电源管理相关的例程 */ int pci_save_state(struct pci_dev *dev);//drivers\pci\pci.c /*** pci_save_state - 在挂起前保存PCI设备的配置空间* dev: - 我们正在处理的PCI设备*/ int pci_save_state(struct pci_dev *dev) {int i;/* X…

谷歌网络营销方案有几种?​

谷歌作为海外的头部工具&#xff0c;本身其实就有多种工具可以供你使用&#xff0c;在这里说说谷歌那些工具 Google My Business&#xff0c;对于小企业或者本地服务来说&#xff0c;把自己的业务信息优化并完善在Google My Business上是个不错的选择。这样当人们在附近搜索相…

微信小程序云开发教程——墨刀原型工具入门(表单组件)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

【NC223888】红色和紫色

题目 红色和紫色 博弈论&#xff0c;想得出来思路就简单&#xff0c;想不出来就难。一般使用猜测法。 思路 如果小红随意取一个格子涂色&#xff0c;那么小紫怎么涂色才是她的最优选择呢&#xff1f; 假设小紫只能选择小红涂色的格子的相邻格子或者是最近斜对角的一个格子涂色…

LeetCode 2684.矩阵中移动的最大次数:一列一列处理,只记能到哪行(BFS)

【LetMeFly】2684.矩阵中移动的最大次数&#xff1a;一列一列处理&#xff0c;只记能到哪行(BFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/ 给你一个下标从 0 开始、大小为 m x n 的矩阵 grid &#xff0c;矩阵由若干 正 整…

【漏洞复现】大华智慧园区综合管理平台SQL注入漏洞

Nx01 产品简介 大华智慧园区综合管理平台是一款综合管理平台&#xff0c;具备园区运营、资源调配和智能服务等功能。该平台旨在协助优化园区资源分配&#xff0c;满足多元化的管理需求&#xff0c;同时通过提供智能服务&#xff0c;增强使用体验。 Nx02 漏洞描述 大华智慧园区…

Halcon图像预处理、阈值分割

1、blob&#xff08;Binary Large Object&#xff09;是指二值图像中连通区域。 预处理通常包括一系列步骤&#xff0c;例如去噪、形态学操作、特征提取等。 read_image(Image,claudia) get_image_size(Image,Width,Height) dev_open_window_fit_size (0, 0, Width, Width, -1,…

如何在iPhone上恢复已删除的微信聊天记录?

你好&#xff0c;我前几天删除了微信聊天记录。有什么办法可以恢复iPhone上已删除的微信聊天记录吗&#xff1f; 有些人每次使用设备时都会遇到在 iPhone 上丢失消息的风险。特别是&#xff0c;由于多种因素&#xff0c;可能会丢失第三方数据&#xff0c;微信消息也是如此。微…

2024Vue高频面试题

前言: Vue 在前端开发领域拥有强劲的发展势头,以下是一些 Vue 的发展趋势: 1.持续增长的用户数量: Vue 作为一款轻量级、易学易用的前端框架,吸引了越来越多的开发者和企业选择使用。其活跃的社区和丰富的资源也促进了用户数量的不断增长。 2.生态系统不断丰富: 随着 V…

远超预期,特效吹爆!《武庚纪》:建议漫改都按这个标准来!

作为《武庚纪》动画党&#xff0c;听闻要改编成真人电视剧时&#xff0c;最害怕的无非五毛钱特效&#xff0c;流水线仙侠&#xff0c;无脑古偶。但在看过《烈焰》&#xff08;原名&#xff1a;武庚纪&#xff09;之后&#xff0c;不得不感叹一句&#xff1a;“倒也不用这么还原…

【计算机网络篇】计算机网络的性能指标

文章目录 &#x1f354;计算机网络的性能指标&#x1f5c3;️常见的计算机网络性能指标⭐速率⭐带宽⭐吞吐量⭐时延⭐时延带宽积⭐往返时间⭐利用率⭐丢包率 &#x1f50e;总结 &#x1f354;计算机网络的性能指标 计算机网络的性能指标被用来从不同方面度量计算机网络的性能 …

算法的渐进时间复杂度

T(n) = O(F(n)) T(n):Time 渐进时间复杂度 O:正比例关系 F(n):代码执行次数 只要代码执行的次数越来越多 所耗费的时间也就越来越高 常见的5种: O(n^2) O(n logn) O(n) O(logn) O(1):不管重复多少次1次也是这个时间,10次也是这个时间。 时间复杂度排序:由小到…

JAVA22 FFM实战之HelloWorld

前言 JDK22即将发布&#xff0c;Java Foreign Function & Memory API将会退出预览&#xff0c;是时候开始学习一波了。 FFM API介绍 FFM API由两大部分组成&#xff0c;一个是Foreign Function Interface&#xff0c;另一个是Memory API。前者是外部函数接口&#xff0c…

对模型性能进行评估(Machine Learning 研习十五)

在上一篇我们已然训练了一个用于对数字图像识别的模型&#xff0c;但我们目前还不知道该模型在识别数字图像效率如何&#xff1f;所以&#xff0c;本文将对该模型进行评估。 使用交叉验证衡量准确性 评估模型的一个好方法是使用交叉验证&#xff0c;让我们使用cross_val_score…

机器学习-04-分类算法-02贝叶斯算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法与贝叶斯算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程…

MySQL大小写敏感、MySQL设置字段大小写敏感

文章目录 一、MySQL大小写敏感规则二、设置数据库及表名大小写敏感2.1、查询库名及表名是否大小写敏感2.2、修改库名及表名大小写敏感 三、MySQL列名大小写不敏感四、lower_case_table_name与校对规则4.1、验证校对规则影响大小写敏感4.1、验证校对规则影响排序 五、设置字段内…

Selenium控制已运行的Edge和Chrome浏览器——在线控制 | 人机交互(详细启动步骤和bug记录)

文章目录 前期准备1. 浏览器开启远程控制指令&#xff08;1&#xff09;Edge&#xff08;2&#xff09;Chrome 2. 执行python代码&#xff08;1&#xff09;先启动浏览器后执行代码&#xff08;2&#xff09;通过代码启动浏览器&#xff08;3&#xff09;Bug问题记录1&#xff…

蓝桥杯决赛2023 RE CyberChef2

思路很清晰&#xff0c;爆IV 但是题目出的有点屎&#xff0c;六位字符串&#xff0c;62的6次方&#xff0c;要我爆到猴年马月&#xff1f; 就当练习脚本吧 #Cyber2 wp from Crypto.Cipher import DES, AES from Crypto.Util.Padding import pad, unpad key_des b0a0b0c0…

PHP异世界云商系统开源源码

系统更新与修复列表 1. 基于彩虹的二次开发 - 对彩虹系统进行了二次开发&#xff0c;增强了系统的功能和性能。2. 新增自定义输入框提示内容&#xff08;支持批量修改&#xff09; - 用户可以自定义输入框的提示内容&#xff0c;并支持批量修改&#xff0c;提升用户体验。3. 新…

TCP相关特性

协议段格式 • 源/⽬的端⼝号:表⽰数据是从哪个进程来,到哪个进程去; • 32位序号/32位确认号:后⾯详细讲; • 4位TCP报头⻓度:表⽰该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最⼤⻓度是15*460 • 6位标志位: ◦ URG:紧急指针是否有效 ◦ ACK:确认号是否有效…