文件操作(1)(C语言版)

news2024/11/25 22:59:53

前言:

        

        为什么要学习文件操作:

        1、如果大家写过一些代码,当运行结束的时候,这些运行结果将不复存在,除非,再次运行时这些结果才能展现在屏幕上面,就比如之前写过的通讯录。

        现实中的通讯录可以保存自己写进去的信息,下次方便查找,但是我们写的当程序推出结束后,里面的信息也随之销毁不会保存

      2、  是因为我们运行的结果都存在了内存当中,程序结束后内存中的数据将会自动清空,但是我们找到我们保存在C盘或者是其它盘中的文件数据就算电脑关机也不会被清除,原因是这些文件数据都保存在硬盘中,硬盘中的数据不会自动清空,所以一般我们删除一些文件都是手动删除。

        所以学会文件的相关操作以后,数据就可以直接保存在硬盘当中!!!

文件的分类:

        我们经常看到不同的文件,但是在程序设计的时候文件有以下两种

1、程序文件:

常以 .c \ .obj \ .exe结尾的

        

        

       

2、数据文件:

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

例如:

文本文档.txt,

文件名:

        一个完整的文件,肯定是有完整的文件名,文件名有如下几部分组成:


        文件路径+文件名主干+文件后缀

        例如: c:\code\test1.txt

文件的打开与关闭:

        我们向文件中存储数据的步骤应该是:

        1、打开文件。

        2、输入要存入的数据。

        3、关闭文件。

1、打开文件:

        当我们打开文件前vs会提供给我们一个FILE类型的结构体:

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

        编译器会开辟一个文件信息区,这些文件的地址,名称,大小等等的一些信息会保存在这个地方,不同编译器提供的文件信息可能有所不同。

        我们通常会创建一个FILE*的指针维护文件信息,当打开文件的时候,会返回文件的相关信息的地址,文件的相关内容我们用FILE*去接收。

 fopen打开文件:

        要打开一个文件,我们通常用fopen函数打开,需要包括fopen相关的头文件

        #include<stdio.h>

        当然fopen打开文件有如下的打开方式:

具体打开代码如下:

        

#include<stdio.h>
int main()
{
	FILE* pf = fopen("cool.txt", "w");
    
	return 0;
}

对fopen传参的说明:

   

 第一个"  " 里面写你要打开的文件的文件名,有两种写法:
          第一种相对路径打开:如果文件名称前面什么都不加,那就表示在当前程序存放的路      径下打开
          如果加..\\表示在上一级路径下打开..\\..\\表示在上上级路径下打开
          第二种绝对路径打开写入完整的名称,也就是完整的文件路径,从根目录到该文件      的路径
            例如:D:\cold\2024_6_16_\2024_6_16_

第二个"  "里面写的是你要用哪种方式打开文件
          如果要用写("w")的形式打开,如果相路径中没有对应的文件,就会自己创建一个

当然也有可能文件打开失败,所以要判断一下,fopen函数打开失败的时候会返回NULL

指针:

所以代码改造为:

int main()
{
	FILE*pf = fopen("cool.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	return 0;
}

2、关闭文件

        关闭文件我们用fclose关闭。

        传参只需要传需要关闭文件的的地址。

        代码如下:

	fclose(pf);

        但是关闭完之后,pf变量中存的文件地址是不是还存在呢?

        答案是存在的,这是pf中存的地址不再是我们开辟的了,导致FILE*pf变成了野指针,所以最后要将pf == NULL。

        代码改造如下:

	fclose(pf);
	pf = NULL;

完整文件打开与关闭代码:

int main()
{
	FILE*pf = fopen("cool.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

        

文件的读写操作:

        介绍完文件如何打开与关闭后,需要我们知道如何将我们想要将内容写入文件中

我们需要知道几个函数和相应的功能

流的概念:

数据和外部设备进行相互交互的时候,都是通过流(数据流)进行交互。

并不是直接进行信息交换的!

        传输不同的数据的时候,我们需要把数据传输到不同的流当中,当然在c语言运行的时候,编译器会自动打开三个标准流,使得我们可以直接传输:

1、标准输入流:stdin

2、标准输出流:stdout

3、标准错误流:stderr

在我们使用printf在屏幕上打印一些数据的时候就要用到标准输出流

在我们使用scanf从键盘上获取数据到内存中的时候就要用到标准输入流

这里的流也可以理解为FILE*的指针!

有上述一些输入输出函数和流的基本概念,接下来我们一个一个探讨和举例。

fgetc和fputc函数

fputc字符输出函数

使用如下:

int main()
{
	FILE* pf = fopen("cool.txt", "w");//写入文件要用"w"
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputc('a',pf);//输出字符
	fclose(pf);
	pf = NULL;
	return 0;
}

两个参数:

第一个参数:传入想写的字符。

第二个参数:是写你要通过哪个流传入,也就是文件的地址

效果如下:

那如果我想要穿多个字符进去,该怎么传进去?

在使用fgetc的时候每传进去一个字符,它的光标自动就会往右移一个位置,等待下一个数据传入。

int main()
{
	FILE* pf = fopen("cool.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputc('a',pf);
	fputc('b', pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

cool.txt文件中就不会打印出ab呢?

最终会打印ab,也就证实了每当用fgetc输出一个字符,对应的字符指针(光标)会自动往后移一个

可以用循环打印字母表:

int main()
{
	FILE* pf = fopen("cool.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char pc = 0;
	for (pc = 'a'; pc <= 'z'; pc++)
	{
		fputc(pc, pf);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

当然此时我不想让它输出到文件中,我想让它输出到屏幕上,我们可以用标准输出流:

代码如下:

int main()
{
	FILE* pf = fopen("cool.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char pc = 0;
	for (pc = 'a'; pc <= 'z'; pc++)
	{
		fputc(pc, stdout);//文件的地址换成标准输出流
	}
	fclose(pf);
	pf = NULL;
	return 0;
}


输出结果:

fgetc字符输入函数:

前提:

在用这个函数的时候打开文件的时候我们需要将打开方式变为只读的形式,一定要相互匹配。

此时我在txt文件中输入abcd。

可以用fgtec读取并存入变量中,代码如下:

int main()
{
	FILE* pf = fopen("cool.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr = fgetc(pf);
	printf("%c\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

fgets和fputs函数

fputs字符串输出函数:

        该函数可以将字符串输出到文件中,代码如下:

int main()
{
	FILE* pf = fopen("cool.txt", "w");//必须是写的形式打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("abcde", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

其函数和字符函数fputc比较相似,只不过传入的字符变成字符串。

fgets字符串输入函数:

        将字符串输入到内存中,保存在字符数组中并打印。

不一样的是,fgets参数有三个:

第一个参数是:你要讲字符串输入到什么地方,

第二个参数是:输入的字符的个数包括\0也就是你想输入3个字符,这里num必须是4,因为这4个里面有一个是\0。

第三个参数是:文件的地址。

例如:

我在文本文件中输入abcde,然后在屏幕上打印abc,我应该传入哪些参数?

代码如下:

int main()
{
	FILE* pf = fopen("cool.txt", "r");//这里一定要用读的形式打开
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20];
	fgets(arr, 4, pf);
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

fscanf和fprintf函数

fprintf格式化输出函数:

那么它和printf的区别在哪?

fprintf有两个参数,相较于printf多了第一个参数——文件地址。

fprintf函数的使用:

int main()
{
	FILE* pf = fopen("cool.txt", "w");//以写的方式打开
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[] = { "i love world" };
	fprintf(pf, "%s\n%d\n", arr,3);
	fclose(pf);
	pf = NULL;
	return 0;
}

这个格式化输出函数传入数据就十分方便了。

想穿什么类型的数据都可以,只要格式正确。

fscanf格式化输入函数:

这里的fscanf和scanf的区别是什么呢?

注意fscanf还是需要多一个参数,文件的地址,而且,fscanf当遇到第一个非空格字符开始输入,当再次遇到空格字符就会停止输入!!!

就比如:

fscanf字符光标一直往后找,找到第一个非空格字符读取,每读一个光标往后移一个,直到再次遇到空格字符停止读取。

int main()
{
	FILE* pf = fopen("cool.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20];
	/*int n = 8;*/
	fscanf(pf, "%s", arr);
	/*fscanf(pf, "%d", &n);*/
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
} 

此时运行结果:

当写成这样:

运行结果:

当然要想读取不同类型的数据,我们可以将不同类型的数据用空格字符隔开,然后多次利用fscanf读取!

例如:

int main()
{
	FILE* pf = fopen("cool.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20];
	int n = 8;
	float a = 0;
	fscanf(pf, "%s", arr);
	fscanf(pf, "%d", &n);
	fscanf(pf, "%f", &a);
	printf("%s %d %f\n", arr,n,a);
	fclose(pf);
	pf = NULL;
	return 0;
} 

fread和fwrite函数

fwrite二进制输出函数:

注:此时文档是二进制文档,文档中存的是数据的二进制

 

有四个参数:

第一个参数:需要传入输出的变量的地址

第二个参数:需要传入每一个变量的大小。

第三个参数:数据的个数

第四个参数:文件的地址

int main()
{
	FILE* pf = fopen("cool.txt","wb");
	if (pf == NULL)
	{
		perror("fopen");
	}
	char arr[] = {"abcde"};
	int arr1[] = {1,2,3,4,5,6};
	fwrite(arr1,sizeof(int),6,pf);
	fwrite(arr, sizeof(char), 5, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

fread二进制输入函数:

它需要的参数和fwrite是一样的,但是我们需要注意

fread的返回值类型是size_t类型,返回读取到的数据的个数!!

这里应该做一个判断。

int main()
{
	FILE* pf = fopen("cool.txt","rb");//二进制读文件
	if (pf == NULL)
	{
		perror("fopen");
	}
	int i = 0;
	char arr[] = {"abcde"};
	int arr1[] = {1,2,3,4,5,6};
	fread(arr1,sizeof(int),6,pf);
	fread(arr, sizeof(char), 5, pf);
	for (i = 0; i < 6; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("%s", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

sprintf和sscanf函数

sprintf函数:

是将格式化的数据转化成字符串。

例如:

struct S
{
	int n;
	float a;
	char b;
};
int main()
{
	struct S s = { 10,(float)3.14,'a' };
	char arr[100];
	sprintf(arr,"%d %lf %c",s.n,s.a,s.b);
	printf("%s\n", arr);
	return 0;
}

sscanf函数:

是将字符串中的数据转换为格式化数据

struct S
{
	int n;
	float a;
	char b;
};
//int main()
//{
//	struct S s = { 10,(float)3.14,'a' };
//	char arr[100];
//	sprintf(arr,"%d %lf %c",s.n,s.a,s.b);
//	printf("%s\n", arr);
//	return 0;
//}

int main()
{
	struct S s = { 10,(float)3.14,'a' };
	char arr[100];
	sprintf(arr,"%d %f %c",s.n,s.a,s.b);
	sscanf(arr, "%d %f %c", &(s.n), &(s.a), &(s.b));
	printf("%d\n", s.n);
	printf("%f\n", s.a);
	printf("%c\n", s.b);
	return 0;
}

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

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

相关文章

商超智能守护:AI监控技术在零售安全中的应用

结合思通数科大模型的图像处理、图像识别、目标检测和知识图谱技术&#xff0c;以下是详细的商超合规监测应用场景描述&#xff1a; 1. 员工仪容仪表监测&#xff1a; 利用图像识别技术&#xff0c;系统可以自动检测员工是否按照规范整理妆容、穿着工作服&#xff0c;以及是否…

Arm和高通的法律之争将扰乱人工智能驱动的PC浪潮

Arm和高通的法律之争将扰乱人工智能驱动的PC浪潮 科技行业高管和专家表示&#xff0c;两大科技巨头之间长达两年的法律大战可能会扰乱人工智能驱动的新一代个人电脑浪潮。 上周&#xff0c;来自微软(Microsoft)、华硕(Asus)、宏碁(Acer)、高通(Qualcomm)等公司的高管在台北举行…

Raylib的贪吃蛇

配置Raylib库 工具链主函数模板Draw: 绘制网格Snake: 初始化Draw&#xff1a;绘制蛇与果Input&#xff1a;移动Logic&#xff1a;游戏主要逻辑Draw: 游戏结束 工具链 mkdir snake cd snakeCMakeLists.txt cmake_minimum_required(VERSION 3.10) project(snake) set(CMAKE_EXP…

深度学习500问——Chapter11:迁移学习(3)

文章目录 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 11.3.2 边缘分布自适应 11.3.3 条件分布自适应 11.3.4 联合分布自适应 11.3.5 概率分布自适应方法优劣性比较 11.3.6 特征选择 11.3.7 统计特征对齐方法 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 数据分布自适…

libdrm 2.4.107 needed because amdgpu has the highest requirement

libdrm 2.4.107 needed because amdgpu has the highest requirement 1.问题分析解决 1.问题 Message: libdrm 2.4.107 needed because amdgpu has the highest requirement Run-time dependency libdrm_intel found: YES 2.4.107 Run-time dependency libdrm_amdgpu found: Y…

深度学习500问——Chapter11:迁移学习(4)

文章目录 11.3.8 流形学习方法 11.3.9 什么是finetune 11.3.10 finetune为什么有效 11.3.11 什么是网络自适应 11.3.12 GAN在迁移学习中的应用 参考文献 11.3.8 流形学习方法 什么是流行学习&#xff1f; 流行学习自从2000年在Science上被提出来以后&#xff0c;就成为了机器…

uniapp canvas生成海报

效果 封装组件&#xff0c;父组件 ref 调用 downImgUrl()函数&#xff0c;其他根据自己需求改 <template><view><view class"bgpart"><canvas class"canvas-wrap" canvas-id"canvasID" type"2d"></canvas…

41、基于深度学习的自适应线性预测(matlab)

1、原理及流程 自适应线性预测是一种基于递归最小二乘法&#xff08;Recursive Least Squares, RLS&#xff09;的线性预测方法&#xff0c;用于自适应地估计线性系统的参数。下面是自适应线性预测的原理和流程&#xff1a; 原理&#xff1a; 自适应线性预测的核心思想是通过…

Java | Leetcode Java题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; class Solution {public int findPeakElement(int[] nums) {int n nums.length;int left 0, right n - 1, ans -1;while (left < right) {int mid (left right) / 2;if (compare(nums, mid - 1, mid) < 0 && compare(n…

转型AI产品经理(12):“希克定律”如何应用在Chatbot产品中

信息过载&#xff0c;这个对现代人来说是很常见的问题&#xff0c;信息获取变得越来越便捷的同时&#xff0c;也导致信息过载让我们无法及时做出有效决策&#xff0c;还可能演变成选择困难症。信息过载对用户体验的设计也有着显著的负面影响&#xff0c;如果我们的产品设计让人…

HTML静态网页成品作业(HTML+CSS)——美食火锅介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

笔记 | 软件工程06-2:软件设计-软件体系结构设计

1 软件体系结构的概念 1.1 软件体系结构的设计元素 1.2 不同的抽象层次 1.3 软件体系结构的不同视图 1.3.1 软件体系结构的逻辑视图&#xff1a;包图 1.3.2 软件体系结构的逻辑视图&#xff1a;构件图 1.3.3 软件体系结构的开发视图 1.3.4 软件体系结构的部署视图 1.3.4.1 描述…

UV胶带和UV胶水的应用场景有哪些不同吗?

UV胶带和UV胶水的应用场景有哪些不同吗? UV胶带和UV胶水的应用场景确实存在不同之处&#xff0c;以下是详细的比较和归纳&#xff1a; 一&#xff1a;按使用场景来看&#xff1a; UV胶带的应用场景&#xff1a; 包装行业&#xff1a;UV胶带在包装行业中常用于食品包装、药…

About Apple Pay

本文翻译整理自&#xff1a;About Apple Pay &#xff08;更新时间&#xff1a;2017-03-16&#xff09; https://developer.apple.com/library/archive/ApplePay_Guide/index.html#//apple_ref/doc/uid/TP40014764 文章目录 一、关于 Apple Pay1、使用 Apple Pay2、测试 Apple …

Kaggle比赛:成人人口收入分类

拿到数据首先查看数据信息和描述 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desk…

【机器学习300问】121、RNN是如何生成文本的?

当RNN模型训练好后&#xff0c;如何让他生成一个句子&#xff1f;其实就是一个RNN前向传播的过程。通常遵循以下的步骤。 &#xff08;1&#xff09;初始化 文本生成可以什么都不给&#xff0c;让他生成一首诗。首先&#xff0c;你需要确定采样的起始点。这可以是一个特殊的开…

深度学习:从理论到应用的全面解析

引言 深度学习作为人工智能&#xff08;AI&#xff09;的核心技术之一&#xff0c;在过去的十年中取得了显著的进展&#xff0c;并在许多领域中展示了其强大的应用潜力。本文将从理论基础出发&#xff0c;探讨深度学习的最新进展及其在各领域的应用&#xff0c;旨在为读者提供全…

外网怎么访问内网?

当我们需要在外网环境下访问内网资源时&#xff0c;常常会面临一些困扰。通过使用一些相关的技术与工具&#xff0c;我们可以轻松地实现这一目标。本文将介绍如何通过【天联】组网产品&#xff0c;解决外网访问内网的问题。 【天联】组网是一款由北京金万维科技有限公司自主研…

事务所管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;客户管理&#xff0c;评论管理&#xff0c;基础数据管理&#xff0c;公告信息管理 客户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;律师管理&#xff0…