C语言中常用的文件操作

本文将介绍常用的关于文件操作函数,如fopen,fclose,fread,fwrite,feek,ftell,rewind以及feof和ferror等文件操作操作函数,还介绍一些用于所有输入输出流的函数如fgetc,fputc,fgets,fputs,fprintf,fscanf等函数,还介绍了sscanf,sprintf函数,feof和ferror函数。最后介绍了文件文件缓冲区的存在。

目录

1、文件的介绍

2、文件的打开和关闭

①流的介绍

②文件指针

③文件的打开和关闭

④顺序读写函数介绍 

(1)fgetc函数介绍

(2) fputc函数介绍

(3)fgets函数介绍

(4)fputs函数介绍

(5)fscanf函数介绍

(6)fprintf函数介绍

(7)fwrite函数介绍

(8)fread函数介绍

3、scanf,printf,sscanf,sprintf,fscanf,fscanf函数的区别

(1)sscanf函数介绍

(2)sprintf函数介绍

4、文件的随机读写

(1)ftell函数介绍

(2)rewind

5、文件读取结束的判定 

feof函数介绍

ferror函数介绍

6、文件缓冲区


1、文件的介绍

我们写的程序的数据是存储在电脑的内存中,当程序退出,内存回收,数据就会丢失,当再次想要看到上次程序的结果是看不到的,想要将数据进行持久化的保存(程序退出其数据不丢失),我们可以使用文件来对这些数据进行保存。

从文件功能方面来分类,文件有程序文件和数据文件。程序文件包括源程序文件(如后缀为.c文件),目标文件(Windows系统其后缀名为.obj),可执行文件(Windows系统下其后缀名为.exe)。数据文件,其文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件或输出内容的文件。下面介绍的是数据文件。根据数据的组织形式,数据文件被称为二进制文件和文本文件,如果数据在内存中以二进制的形式存储(不经任何转换),直接输出到外存文件中,这就是二进制文件。如果在外存中以ASCII码的形式存储,在存储前需要进行转换,以ASCII码的形式存储的文件就是文本文件。数据存储到外存的这个文件即可以二进制的形式进行存储也可以ASCII码的形式进行存储。这个区分主要是看这个外存(硬盘)里的存储的是二进制还是ASCII码的形式。注意,计算机中的数据在内存中都是二进制进行存储的,是文本文件还是二进制文件是针对外存(也就是硬盘来说的)。

2、文件的打开和关闭

①流的介绍

程序的数据可能会输出到各种外部设备,也可能从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,所以就抽象出来了流的概念。C语言程序对文件,画图,键盘等数据的输入操作都是通过流操作的。一般情况下,要想向流里写数据或者从流中读取数据都是要打开流然后进行操作。

值得注意的是,从键盘输入数据和向屏幕里打印信息都没有打开流,这是由于C语言程序在启动的时候默认打开了3个流(stdin,stdout,stderr)。

stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输入流中读取数据。
stdout - 标准输出流,大多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出
流中。
stderr - 标准错误流,大多数环境中输出到显示器界面。
stdin、stdout、stderr三个流的类型是: FILE * ,通常称为文件指针

C语⾔中,就是通过 FILE* 的文件指针来维护流的各种操作的

②文件指针

缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”

每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名为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指向某个⽂件的⽂件信息区(是⼀个结构体变量)。通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件。

③文件的打开和关闭

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

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

#include<stdio.h>
int main()
{FILE* pf = fopen("data.txt", "w");//以写的形式打开data.txt文件if (pf == NULL){perror("fopen");return 1;}//进行文件操作//关闭文件fclose(pf);pf = NULL;return 0;
}

④顺序读写函数介绍 

所有输⼊流⼀般指适⽤于标准输⼊流和其他输⼊流(如⽂件输⼊流);所有输出流⼀般指适⽤于标准输出流和其他输出流(如⽂件输出流)。

需要注意的是,对流进行操作的时候一定要与对应的函数就行操作,如对文件操作,对文件以读的形式打开那就只能读取文件的信息而不能向文件输出信息,同样地,如果以写的形式打开,那就只能对文件进行写操作而不能对其进行读操作,如果需要又读又写那就需要再打开文件的时候设定读写的模式。

(1)fgetc函数介绍

FILE*表示一个流,(如文件流或标准输入输出流),该函数读取流中的一个字符,当读到文件末尾或读取错误的时候会返回一个EOF。当需要将一个流的信息都读取出来可以使用这个函数一个字符一个字符的读取直至返回值为EOF(读取结束),下面将使用代码展示

代码示例:

#include<stdio.h>
int main()
{FILE* pf = fopen("data.txt", "r");//以读的形式打开data.txt文件if (pf == NULL){perror("fopen");return 1;}//进行文件操作char ch = 0;while ((ch = fgetc(pf)) != EOF)//当fgetc返回值不为EOF就表示在没有读取失败或还没到文件末尾{printf("%c", ch);}//关闭文件fclose(pf);pf = NULL;return 0;
}

其中data.txt文件(与C语言的源文件在同一个目录底下)的内容如下:

最后结果如下: 

(2) fputc函数介绍

该函数的功能是向流中写一个字符 ,如果写入成功将返回该字符,写入失败就会返回EOF。

代码示例:

#include<stdio.h>
int main()
{FILE* pf = fopen("data.txt", "w");//以读的形式打开data.txt文件if (pf == NULL){perror("fopen");return 1;}//进行文件操作,向data.txt文件写入一个字符xfputc('x', pf);//关闭文件fclose(pf);pf = NULL;return 0;
}

(3)fgets函数介绍

该函数是向流中的数据读取num个字符将其放到str这个指针所指向的空间。如果读取成功就返回str(其实就是这个字符串的地址),如果读取失败或读到文件结尾就会返回NULL。当需要将一个流的信息都读取出来可以使用这个函数一次读取num个,直至返回值为NULL(读取结束),下面将使用代码展示

代码示例:

#include<stdio.h>
int main()
{FILE* pf = fopen("data.txt", "r");//以读的形式打开data.txt文件if (pf == NULL){perror("fopen");return 1;}char ch[20] = { 0 };while (fgets(ch, 5, pf)!=NULL)//将data.txt文件的内容每次读取5个放到ch数组中,直至读取错误或文件末尾{printf("%s", ch);//将读取的}//关闭文件fclose(pf);pf = NULL;return 0;
}

(4)fputs函数介绍

该函数是将str指向的内容写到流中,如果写入成功就会返回应该非0的数,如果写入失败就会返回0。

代码示例:

#include<stdio.h>
int main()
{FILE* pf = fopen("data.txt", "w");//以读的形式打开data.txt文件if (pf == NULL){perror("fopen");return 1;}char ch[30] = "asdfahyrhdfgqefd7890";fputs(ch, pf);//关闭文件fclose(pf);pf = NULL;return 0;
}

(5)fscanf函数介绍

该函数的功能是从流中读取数据并按特定的格式存储到format这个参数里(这个参数与scanf类似)。如果在读取过程中发生读取错误或到达文件末尾,会设置相应的指示器(feof或ferror)。如果在任何数据成功读取之前发生其中之一,则返回EOF。

代码示例:

#include<stdio.h>
int main()
{char ch[30] = { 0 };FILE* pf = fopen("data.txt", "r");//以读的形式打开文件fscanf(pf, "%s", ch);printf("%s\n", ch);return 0;
}

 (6)fprintf函数介绍

该函数是将format所指向的字符内容输出到stream这个流中,如果发生写入错误,文件错误指示器(ferror)会被设置,同时函数通常会返回一个负数,用以表示错误的发生。如果成功的话就会返回写入流中字符的个数。

代码示例:

#include<stdio.h>
int main()
{char ch[30] = "12345679zxcvasdfbgre";FILE* pf = fopen("data.txt", "w");//以写的形式打开文件fprintf(pf, "%s", ch);printf("%s\n", ch);return 0;
}

 

 (7)fwrite函数介绍

该函数是将ptr所指向的size*count个字节的内容写入到流中,返回值成功写入的个数。该函数是对二进制文件进行操作的。

#include<stdio.h>
int main()
{char ch[30] = "12345679zxcvasdfbgre";FILE* pf = fopen("test", "wb");//以二进制读写的形式打开文件fwrite(ch,sizeof(char), sizeof(ch), pf);//char tmp[30] = { 0 };//fread(tmp, sizeof(char), sizeof(tmp), pf);//printf("%s\n", tmp);return 0;
}

(8)fread函数介绍

该函数向流中取size*count个字节的数据放入到ptr所指向的空间。返回的是读取成功的个数。可以通过每次读取一个直至返回值为0就表示读取结束或读取失败。这可以通过ferror或feof来对其进行判断,看是正常结束还是不正常结束。需要注意的是该函数是对二进制文件进行读取的

代码示例:

#include<stdio.h>
int main()
{//char ch[30] = "12345679zxcvasdfbgre";FILE* pf = fopen("test", "rb");//以二进制读写的形式打开文件//fwrite(ch,sizeof(char), sizeof(ch), pf);char tmp[30] = { 0 };fread(tmp, sizeof(char), sizeof(tmp), pf);printf("%s\n", tmp);return 0;
}

需要注意的是,这些函数如果对文件流进行操作时,打开文件的时候要留意是读文件还是写文件,可以从文件中读取的有fgetc,fgets,fscanf,fread函数。而将数据输出到文件中的函数有fputc,fputs,fprintf,fwrite函数。fwrite和fread只能针对文件流进行操作(还是以二进制进行操作的),而上面其余的函数是针对所以输入或输出流。

3、scanf,printf,sscanf,sprintf,fscanf,fscanf函数的区别

 (1)sscanf函数介绍

 该函数是在字符串读取格式化的数据。

代码示例:

#include<stdio.h>
int main()
{char str[15] = "10 1.23 avb";int a = 0;float b = 0;char ch[5] = { 0 };sscanf(str, "%d%f%s", &a, &b, ch);printf("%d\n", a);printf("%f\n", b);printf("%s\n", ch);return 0;
}

(2)sprintf函数介绍

 

该函数是把格式化的数据转化成字符串

#include<stdio.h>
int main()
{char str[30] = "10 1.23 avb";int a = 0;float b = 0;char ch[5] = { 0 };char tmp[30] = { 0 };sscanf(str, "%d%f%s", &a, &b, ch);sprintf(tmp, "%d %f %s", a, b, ch);printf("%s", tmp);return 0;
}

小结:scanf从标准输入流读取格式化数据,fscanf从指定的输入流上读取格式化的数据,sscanf在字符串中读取格式化的数据。printf把数据以格式化的形式打印在标准输出流上,fprintf把数据以格式化的形式输出到指定的流,sprintf把格式化的数据转化成字符串。

4、文件的随机读写

(1)fseek函数介绍

#include<stdio.h>
int main()
{FILE*pf=fopen("tt.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("This is an apple.", pf);fseek(pf, 9, SEEK_SET);//通过设置后两个参数,来设定光标的位置fputs(" sam", pf);char ch = 0;while ((ch=fgetc(pf))!=EOF){printf("%c", ch);}fclose(pf);return 0;
}

 (1)ftell函数介绍

 

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

#include<stdio.h>int main()
{FILE*pf=fopen("tt.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("This is an apple.", pf);fseek(pf, 9, SEEK_SET);fputs("xxx",pf);int ret=ftell(pf);printf("%ld\n", ret);//打印的是光标相对于起始的偏移量return 0;
}

(3)rewind

让光标回到文件的起始位置。

#include<stdio.h>int main()
{FILE*pf=fopen("tt.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("This is an apple.", pf);fseek(pf, 9, SEEK_SET);fputs("xxx",pf);int ret=ftell(pf);printf("%ld\n", ret);//打印的是光标相对于起始的偏移量rewind(pf);ret = ftell(pf);printf("%ld\n", ret);//打印的是光标相对于起始的偏移量return 0;
}

5、文件读取结束的判定 

feof函数介绍

在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。feof 的作用是:当文件读取结束的时候,判断是读取结束的原因是否是:遇到文件尾结束。如果是遇到文件末尾结束的话就会返回一个非0的数,如果不是文件末尾结束的话将返回0。

ferror函数介绍

如果设置了与流关联的错误指示符,则返回一个非零值。否则,返回0。

6、文件缓冲区

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

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不刷新缓冲区或关闭文件可能会导致数据丢失等问题。

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

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

相关文章

【Java扫盲篇】String、String Buffer和String Builder的区别

你在面试时&#xff0c;面试官让你讲讲String String Buffer String Builder的区别&#xff0c;你是否能流畅的、完整的叙述出他们三者的区别? ✍先说结论 相同点&#xff1a; 他们的底层都是由char数组实现的。不同点&#xff1a; String对象一旦创建&#xff0c;是不能修…

基于STM32温室智能监测控制系统设计

**单片机设计介绍&#xff0c;基于STM32温室智能监测控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于STM32的温室智能监测控制系统设计是一个综合性的项目&#xff0c;旨在实现对温室内环境参数的实时监测和控制…

2024年14款国内外主流低代码开发平台对比:总有一款适合您!

低代码开发平台是一种更偏向于赋能技术人员的工具&#xff0c;它允许开发人员通过将可视代码块拖放到工作流中来创建应用程序&#xff0c;从而以最少的手工编码快速设计应用程序。 市场中有非常多的低代码开发平台&#xff0c;令人眼花缭乱。应当选哪个低代码开发平台&#xf…

12 完全分布式搭建-SSH免密登录

配置 ssh &#xff08;1&#xff09;基本语法 ssh 另一台电脑的 IP 地址 &#xff08;2&#xff09;ssh 连接时出现 Host key verification failed 的解决方法 [ytmaster~]$ ssh slave01 ➢ 如果出现如下内容 Are you sure you want to continue connecting (yes/no)…

代码随想录算法训练营Day36|LC435 无重叠区间LC763 划分字母区间LC56 合并区间

一句话总结&#xff1a;都是和昨天的用最少箭引爆气球类似的题。 原题链接&#xff1a;435 无重叠区间 计数不重叠的区间的个数&#xff0c;然后用总长度减去这个值即可。 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, (a,…

2.4 比较检验 机器学习

目录 常见比较检验方法 总述 2.4.1 假设检验 2.4.2 交叉验证T检验 2.4.3 McNemar 检验 接我们的上一篇《性能度量》&#xff0c;那么我们在某种度量下取得评估结果后&#xff0c;是否可以直接比较以评判优劣呢&#xff1f;实际上是不可以的。因为我们第一&#xff0c;测试…

谭浩强第五版C语言课后习题(编程题)+答案

谭浩强第五版作为初学C语言必读的一本教材&#xff0c;课后习题具有非常大的参考价值&#xff0c;也是很多高校期末考试或者考研的重要参考。在这里我整理了一部分个人认为比较重要的编程题&#xff0c;供大家作参考 1.输入两个数&#xff0c;求他们的最大公约数和最小公倍数&…

区间开关灯模型

P3870 [TJOI2009] 开关 先看一道经典的区间开关灯问题的模型&#xff0c;维护一个lz 每次异或操作就好了 #include<bits/stdc.h> using namespace std; using ll long long; using pii pair<int,int>; const int N 1e510; const int inf 0x3f3f3f3f; const int…

RCG如何将带有噪声的表征+条件输入RDM并得到去噪的表征

一、有条件去噪控制 很简单的一个模型&#xff0c;整体来说就是将“内容&#xff08;图像&#xff09;” “图像所对应的标签” “每个噪声表征对应的时间步Timestap”分别输入进线性层Layer&#xff0c;然后将他们的表征相加&#xff08;&#xff09;即可 执行步骤是&…

FCP270 P0917YZ 兼容性如何

FCP270 P0917YZ 是一种现场控制处理器&#xff0c;通常应用于工业自动化和过程控制系统中。 这款现场控制处理器的主要职责是监测和控制多种过程变量&#xff0c;确保系统的正常运行&#xff0c;并且满足生产的要求。以下是关于FCP270 P0917YZ的一些可能用途和特点&#xff1a…

HWOD:名字的漂亮度

一、题目 描述 给出一个字符串&#xff0c;该字符串仅由小写字母组成&#xff0c;定义这个字符串的漂亮度是其所有字母漂亮度的总和 每个字母都有一个漂亮度&#xff0c;范围在1到26之间。没有任何两个不同字母拥有相同的漂亮度。字母忽略大小写。 给出多个字符串&#xff…

船舶航行突发事故3D模拟仿真演练优化搜救路线

在波澜壮阔的海洋世界中&#xff0c;船舶事故与搜救行动始终牵动着无数人的心。为了更好地应对这些挑战&#xff0c;我们倾力打造了3D船舶事故和搜救情景再现系统&#xff0c;旨在以科技之力为海事安全保驾护航。 该系统采用先进的web3D开发渲染技术&#xff0c;能够真实模拟船…

实验3 中文分词

必做题&#xff1a; 数据准备&#xff1a;academy_titles.txt为“考硕考博”板块的帖子标题&#xff0c;job_titles.txt为“招聘信息”板块的帖子标题&#xff0c;使用jieba工具对academy_titles.txt进行分词&#xff0c;接着去除停用词&#xff0c;然后统计词频&#xff0c;最…

火山引擎VeDI:A/B测试开放平台正式上线,企业个性化平台一键定制

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 火山引擎数智平台VeDI旗下的A/B测试平台&#xff08;DataTester&#xff09;&#xff0c;旨在为企业提供科学且可信的A/B测试能力及丰富的场景实验支持。随着企业的…

java常用优秀开发框架及工具类汇总

目录 1、各类系统及简称扫盲2、开发框架2.1、若依(ruoyi) 3、工具组件3.1、java工具类库3.1.1、HuTool3.1.2、office、excel、pdf文档处理3.1.3、运行日志管理3.1.4、数据层框架3.1.5、数据库连接池 java发展了很多年&#xff0c;为了便于开发&#xff0c;出现刴优秀的开发框架…

知识图谱操作的探索与利用

目录 前言1 搜索&#xff08;Search&#xff09;1.1 基于关键词搜索1.2 属性搜索1.3 模式匹配 2 过滤&#xff08;Filtering&#xff09;2.1 属性过滤2.2 关系过滤 3 引导&#xff08;Guidance&#xff09;3.1 相关实体推荐3.2 路径推荐 4 合并&#xff08;Merging&#xff09;…

WPF自定义Panel:让拖拽变得更简单

在 WPF 应用程序中&#xff0c;拖放操作是实现用户交互的重要组成部分。通过拖放操作&#xff0c;用户可以轻松地将数据从一个位置移动到另一个位置&#xff0c;或者将控件从一个容器移动到另一个容器。然而&#xff0c;WPF 中默认的拖放操作可能并不是那么好用。为了解决这个问…

智慧公厕的技术融合策略

智慧公厕是迎合现代城市发展需要的一项重要基础设施&#xff0c;其设计的技术融合策略在实现公共厕所泛在感知、互通互联、协同构筑智慧城市等方面起到了关键作用。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案例现场实景实图实例&#xff0c;从物…

数字兆欧表的量程选择技巧,你需要知道的秘密!

使用数字兆欧表的方法如下&#xff1a; 步骤一&#xff1a;准备工作 在开始操作之前&#xff0c;务必确保待测电气设备已经断电并进行了充分放电&#xff0c;以保证操作的安全性。此外&#xff0c;还需检查数字兆欧表的电量是否足够&#xff0c;外观是否完好&#xff0c;并确保…

元宇宙虚拟展厅——虚拟场景同现实世界的结合宣传

元宇宙作为具有前瞻性和先导性的未来产业&#xff0c;在政策布局、产业发展以及应用融合等方面也都实现了诸多探索。元宇宙虚拟展厅是虚拟场景同现实世界的结合&#xff0c;元宇宙与展厅的应用融合打破了传统展厅、传统宣传对时间和空间的限制&#xff0c;以往我们印刷过数不胜…