进阶C语言——文件操作(上)

news2024/11/26 2:48:46

本章文章主要是关于文件教学的,大家可能会对C语言中的文件可能有点陌生,这两个看起老来完全扯不上边的东西,但是实际上他们有很多的关联,本章文章将讲解一些文件的打开和关闭,并和一些库函数一起使用之后的效果,让我们来学习吧

为什么使用文件

我们在写程序的时候,每次运行的时候,里面的数据可能就不存在了,当我们想在看到这个内容的时候需要重新运行,就比如我们写的通讯录一样,我们在输入数据的时候,当我们再打开的时候,之前的数据又不在了,那我们得实现一个可以记录信息的东西,那就是文件

只有我们自己选择删除数据的时候,数据才不复存在。这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。
使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

什么是文件呢?

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

程序文件

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

数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

我们先写一个代码然后来看一下什么是程序文件


#include<stdio.h>
int main()
{
	printf("hehe\n");
	return 0;
}

当我们运行起来的时候
在这里插入图片描述
我们在Debug中可以看到我们的可执行程序,后缀为.exe的文件
在这里插入图片描述
再来看看我们的目标文件
在这里插入图片描述
需要返回上一层目录才能找到

那什么是数据文件呢

在这里插入图片描述

我们在test.c的路径下创建一个文本文件,这个就是数据文件,而我们这章的内容就是讲数据文件的

数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

在以前各章所处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件

文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀

例如: c:\code\test.txt

code就是路径,test就是文件名主干,.c就是后缀

文件的打开和关闭

文件在读写的时候我们要打开文件(fopen),使用结束的时候应该关闭文件fclose,这和我们的动态内存开辟有点相似

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”
我们打开一个文件就会出现一个结构体,结构体中放的是文件的信息,我们用一个FILE类型的指针来接收它

在这里插入图片描述

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
       };
typedef struct _iobuf 

这就是我们来存放文件信息的结构体

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建一个FILE*的指针变量:

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

定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

fopen和fclose函数

头文件<stdlib.h>

在这里插入图片描述
在这里插入图片描述
给>fopen是打开文件,fclose是关闭文件,两个要连着用

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

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

在这里插入图片描述
那我们开始来了解下面这个代码,这就是一个简单的文件打开和关闭

/* fopen fclose example */
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//以读的方式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

这是我们以写的方式打开test.txt这个文件

在这里插入图片描述

我们在这个路径下创建test.txt这个文件

大家可能会对这两个有点问题
在这里插入图片描述
一个是从文件里读取内容,一个是把内容写进文件当中
我们先来看看输出,如何把内容写进文件
文件对的顺序读写
在这里插入图片描述

fputc

在这里插入图片描述

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//以读的方式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	fputc('d', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
经过我们的操作,也是成功一个一个字符的把abcd放入我们的test.txt文件当中

还要注意的是以”w“的方式写的话,会先销毁文件的内容

我们如果把fputc的内容注释掉看一下结果

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//以读的方式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	/*fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	fputc('d', pf);*/
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
看到我们文件的内容也没有了

从fpen中可以看出我们放入字符的顺序也是有序的

fgetc

在这里插入图片描述

int fgetc(FILE* stream)

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	//以读的方式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c", ch);
	 ch = fgetc(pf);
	printf("%c", ch);
	 ch = fgetc(pf);
	printf("%c", ch);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

在我们读取到结尾的时候会返回一个EOF或者空指针

在这里插入图片描述
文本行输出函数fputs
在这里插入图片描述

int fputs( const char *string, FILE *stream );

他的作用和fputc一样,效果就是整行的输出
下面我们来看代码


#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//以写的方式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写一行到文件
	fputs("abcdef\n", pf);
	fputs("xxxxxx\n", pf);
	
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
想写在一行的话不加\n就行了
文本行输入函数fgets
在这里插入图片描述

char* fgets(char*string,int n,FILE* steam)

从指定的stream中读取一行,并把它存在一个字符串中,返回这个字符串的地址,当读到最后一个字符或者遇到\n就停止读

#include<stdio.h>
int main()
{
	char arr[20];
	FILE* pf = fopen("test.txt", "r");
	//以读的方式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读一行到文件
	fgets(arr, 6, pf);
	printf("%s", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
这里大家可能有疑问,就是明明写着6,但是为什么我们读取的是5个字符,因为这个是一种保护机制,有时候我们的末尾是\0并不需要读,所以我们读到的字符是n-1个字符

格式化输出函数fprintf

在这里插入图片描述

int fprintf(FILE*stream,const char* format)

fprintf用于对格式化的数据进行写文件,发送格式化输出流中。
格式化的数据可以是结构体

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s1 = { "zhangsan",18,99.9f };
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fprintf(pf, "%s %d %f", s1.name, s1.age, s1.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

fscanf

在这里插入图片描述

int fscanf(FILE* stream,const char*format,...)

fscanf 用于对格式化的数据进行读取,从stream读取格式化输入,适用于所有输入流

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s1 = { "zhangsan",18,99.9f };
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fscanf(pf, "%s %d %f", s1.name, &s1.age, &s1.score);
	printf( "%s %d %f", s1.name, s1.age, s1.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
二进制输出函数fwrite

在这里插入图片描述

写一个数据到流中去,把buffer所指向的数据写到流当中去
在这里插入图片描述

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s1 = { "zhangsan",18,99.9f };
	FILE* pf = fopen("test.txt", "w+");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fwrite(&s1, sizeof(struct stu), 1, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

上面的内容就是二进制,就看不太懂了

那我们可以以二进制读的方式把内容重新读出来

fread
在这里插入图片描述
在这里插入图片描述


#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s1 = { "zhangsan",18,99.9f };
	FILE* pf = fopen("test.txt", "r+");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fread(&s1, sizeof(struct stu), 1, pf);
	printf("%s %d %f", s1.name, s1.age, s1.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

以上就是文件操作的一部分内容,我们分两章来写

----------------------------------
那今天的分享就到这里,谢谢大家

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

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

相关文章

MATLAB计算变异函数并绘制经验半方差图

本文介绍基于MATLAB求取空间数据的变异函数&#xff0c;并绘制经验半方差图的方法。 由于本文所用的数据并不是我的&#xff0c;因此遗憾不能将数据一并展示给大家&#xff1b;但是依据本篇博客的思想与对代码的详细解释&#xff0c;大家用自己的数据&#xff0c;可以将空间数据…

第一百一十五天学习记录:C++提高:STL初识(黑马教学视频)

STL的诞生 1、长久以来&#xff0c;软件界一直希望建立一种可重复利用的东西 2、C的面向对象和泛型编程思想&#xff0c;目的就是重复性的提升 3、大多数情况下&#xff0c;数据结构和算法都未能有一套标准&#xff0c;导致被迫从事大量重复工作 4、为了建立数据结构和算法的一…

samba挂载报错“mount error(13): Permission denied“

“mount error(13): Permission denied” 环境&#xff1a;CentOS7 挂载报错&#xff1a; [rootchenshuyi ~]# mount -t cifs //127.0.0.1/printers /tmp/samba Password for root//127.0.0.1/printers: mount error(13): Permission denied Refer to the mount.cifs(8) manu…

印制电路板中常用标准有哪些?

在PCB电路板中一般都有哪些标准呢&#xff1f;一起来看看。 1) IPC-ESD-2020&#xff1a;静电放电控制程序开发的联合标准。包括静电放电控制程序所必须的设计、建立、实现和维护。根据某些军事组织和商业组织的历史经验&#xff0c;为静电放电敏感时期进行处理和保护提供指导。…

前端:运用html+css+js模仿百度热搜电影榜鼠标移入特效

前端:运用htmlcssjs模仿百度热搜电影榜鼠标移入特效 1. 实现原理2. 界面布局3. js实现对鼠标移入和移出的监听4. 参考代码如下&#xff1a; 1. 实现原理 百度热搜上电影榜鼠标移入特效如上图所示。个人觉得上述特效实现原理为使用相对定位、绝对定位实现的(鼠标移入和没有移入…

OrangePi Zero2 TTL 连接示意图

OrangePi 目前最方便的就是使用调试串口线进行PC与开发板进行链接。 OrangePi Zero2 GPIO引脚图 TTL连接图 本人使用的型号为CH340模块USB转TTL刷机线&#xff0c;Windows下免驱。 黑线对GND接口&#xff0c;绿线对RX接口&#xff0c;白线对TX接口。

element-ui form表单的动态rules校验

在vue 项目中&#xff0c;有时候可能会用到element-ui form表单的动态rules校验&#xff0c;比如说选择了哪个选项&#xff0c;然后动态显示或者禁用等等。 我们可以巧妙的运用element-ui form表单里面form-item想的校验规则来处理&#xff08;每一个form-item项都可以单独校验…

推荐几个Windows iso镜像下载的网站

文章目录 1. 微软官网2. MSDN网站3. 系统库(xitongku)4. 其他网站最后总结 给大家推荐几个 Windows iso镜像下载网站 1. 微软官网 入口地址&#xff1a;https://www.microsoft.com/zh-cn/software-download 以下载Windows11为例&#xff1a; 1&#xff09;找到下载Windows11…

【教程】查看CPU、GPU架构的拓扑结构和系统信息

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 一些概念 Package&#xff1a;处理器封装。在多处理器系统中&#xff0c;每个物理 CPU 芯片通常被封装在一个单独的封装中&#xff0c;这个封装被称为 Package。一个 Package 可以包含一个或多个物理 CPU 核心。…

计算机组成原理复习-例题版

目录 第一章&#xff1a;计算机系统概论 第二章&#xff1a;机器数 第三章&#xff1a;指令 第四章&#xff1a;机器数运算 第六章&#xff1a;CPU 第七章、第八章、第九章 &#xff1a;总线、辅存、中断 第一章&#xff1a;计算机系统概论 第二章&#xff1a;机器数 ​​…

SVG 简单应用

第一步赋值svg 第二步&#xff1a;fill 填充色设置为“” 第三步设置 svg 颜色和大小

基础算法-单链表

单链表 -> 邻接表:主要用于存储图和树。 双链表 : 主要用于优化某些问题。 单链表的相关操作&#xff1a;1.单链表的初始化 2.将x插到头节点 3.将x插入到下标是k的节点后面 4.将下标是k的节点的后面一个节点删除 1.单链表的初始化 代码&#xff1a; //单链表的初始…

第117天:免杀对抗-反VT沙盒反虚拟机反调试进程APC注入项目保护

知识点 #知识点&#xff1a; 1、反VT-沙盒检测-Go&Python&C 2、反调试-调试检测&进程注入-C 3、反VT反调试-程序保护-工具项目类#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修…

Tripwire 完整性分析工具(Linxu系统)

环境&#xff1a;centos7 工作流程&#xff1a; 当前的系统数据状态建立数据库定期比较系统现状与数据库中的状态属性改变有详细报告分析报告发现入侵 1、安装相关软件包 [roothello ~]# yum install epel-release -y 已加载插件&#xff1a;fastestmirror Repository base …

自学网络安全(黑客)全笔记

一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

了解Unity编辑器之组件篇Mesh(三)

Mesh&#xff1a;是一种三维模型的表示形式&#xff0c;它由一系列顶点、三角形&#xff08;或其他多边形&#xff09;和相关属性组成。Mesh用于表示物体的外观和形状&#xff0c;它是可见物体的基本组成部分。通过操作Mesh&#xff0c;开发者可以实现各种视觉效果、物理模拟和…

AI人工智能一键图片/视频换脸-Roop

软件介绍 Roop 换脸技术是一种基于深度学习的人脸图像处理技术。 技术原理 Roop换脸技术的实现主要分为两个步骤&#xff1a;人脸检测与对齐、特征融合与生成。 1.人脸检测与对齐在Roop换脸技术中&#xff0c;首先需要对输入的图像进行人脸检测与对齐。这一步骤的目的是确保…

Ubuntu搭建Samba服务-学习记录

文章目录 Ubuntu安装Samba流程Samba配置文件Samba添加账户配置文件修改Samba服务控制设置开机自动启动通过systemctl 启动服务通过 rc.local 启动 Windows访问参考链接 当前文章仅用于记录&#xff0c;在 Ubuntu中安装使用Samba&#xff0c;在Windows访问 系统环境&#xff1a;…

ChatGPT应用|科大讯飞星火杯认知大模型场景创新赛开始报名了!

ChatGPT发布带来的 AI 浪潮在全球疯狂蔓延&#xff0c;国内掀起的大模型混战已经持续半年之久&#xff0c;国产大模型数量正以惊人的速度增长&#xff0c;据不完全统计&#xff0c;截止7月14号已经达到了111个&#xff0c;所谓的“神仙打架”不过如此了吧。 &#xff08; 包括但…