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

前言:

        

        为什么要学习文件操作:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智游剪辑手机版发布!

耗时一个多月&#xff0c;手机版终于开发的差不多了&#xff0c;下面带大家一起来看下效果咋样吧&#xff01; 功能介绍 打开应用就可以直接看到我们的所有功能了&#xff0c;支持分类查看和关键词搜索功能&#xff0c;每个功能都可以查看帮助教程和收藏&#xff0c;点击即可进…

Day40

Day40 监听器 概念&#xff1a; 监听器用于监听web应用中某些对象信息的创建、销毁、增加&#xff0c;修改&#xff0c;删除等动作的 发生&#xff0c;然后作出相应的响应处理。当范围对象的状态发生变化的时候&#xff0c;服务器自动调用 监听器对象中的方法。 常用于统计在线…

AWS——01篇(AWS入门 以及 AWS之EC2实例及简单实用)AWS

AWS——01篇&#xff08;AWS入门 以及 AWS之EC2实例及简单实用&#xff09; 1. 前言 2. 创建AWS账户 3. EC2 3.1 启动 EC2 新实例 3.1.1 入口 3.1.2 设置名称 选择服务 3.1.3 创建密钥对 3.1.4 网络设置——安全组 3.1.4.1 初始设置 3.1.4.2 添加安全组规则&#xff08;开放新…

0X0-基于Sklearn的机器学习入门:聚类(上)

本节及后续章节将介绍深度学习中的几种聚类算法&#xff0c;所选方法都在Sklearn库中聚类模块有具体实现。本节为上篇&#xff0c;将介绍几种相对基础的聚类算法&#xff0c;包括K-均值算法和均值漂移算法。 目录 X.1 聚类概述 X.1.1 聚类的种类 X.1.2 Sklearn聚类子模块 …

【JVM结构、JVM参数、JVM垃圾回收】

JVM&#xff1a;Java Virtual Machine java虚拟机 虚拟机&#xff1a;使用软件技术模拟出与具有完整硬件系统功能、运行在一个隔离环境中的计算机系统。 JVM官方文档&#xff1a;https://docs.oracle.com/javase/specs/jvms/se8/html/index.html java 一些命令 javac 将文件编…

【C++入门(3)】函数重载、引用

一、函数重载 1、函数重载概念 函数重载是指在同一作用域中&#xff0c;具有不同形参列表&#xff08;参数的 个数 或 类型 或类型顺序 不同&#xff09;的同名函数。 C语言中不允许同名函数的存在&#xff0c;如果一个程序中有两个函数的函数名完全相同&#xff0c;就会报错…

C#(C Sharp)学习笔记_多态【十九】

前言 个人觉得多态在面向对象编程中还比较重要的&#xff0c;而且不容易理解。也是学了一个下午&#xff0c;才把笔记写得相对比较完善&#xff0c;但仍欠缺一些内容。慢慢来吧…… 什么是多态&#xff1f; 基本概念 在编程语言和类型论中&#xff0c;多态&#xff08;Poly…

2024最新版Node.js下载安装及环境配置教程(非常详细)

一、进入官网地址下载安装包 官网&#xff1a;Node.js — Run JavaScript Everywhere 其他版本下载&#xff1a;Node.js — Download Node.js (nodejs.org) 选择对应你系统的Node.js版本 二、安装程序 &#xff08;1&#xff09;下载完成后&#xff0c;双击安装包&#xf…

OpenGL Super Bible 7th-Primitives, Pipelines, and Pixels图元、渲染管线与像素

简介 本文的原版为《OpenGL Super Bible 7th》,是同事给我的,翻译是原文+译文的形势。文章不属于机器直译,原因在于语言不存在一一对应的关系,我将尽可能的按照中国人看起来舒服的方式来翻译这些段子,如果段子让你感到身心愉悦,那还劳烦点个关注,追个更。如果我没有及时…

从0进入微服务需要了解的基础知识

文章目录 系统架构演化过程为什么要了解系统架构的演化过程技术发展认知技术选型与创新 演变过程单体架构分层-分布式集群微服务 分布式\集群\微服务 微服务中的核心要素-拆分原则项目拆分与复杂度微服务的拆分维度有哪些小结 微服务中的核心要素服务化进行拆分后一定是微服务&…

MFC扩展库BCGControlBar Pro v35.0新版亮点:重新设计的工具栏编辑器等

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v35.0已全新发布了&#xff0c;这个版本改进类Visual Studio 2022的视觉主题、增强对多个…

ChatGPT付费创作系统V3.0.2独立版 WEB+H5+小程序端 (H5端界面美化+Pika视频作品广场+SunoAI 文生歌)系统部署教程

播播资源GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序&#xff0c;是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。当前全民热议ChatGPT&#xff0c;流量超级大&#xff0c;引流不要太简单&#xff01;一键下单即可拥有自己的GPT&#xff01;无限…

MinIO Enterprise Cache:实现超性能的分布式 DRAM 缓存

随着计算世界的发展和 DRAM 价格的暴跌&#xff0c;我们发现服务器配置通常配备 500GB 或更多的 DRAM。当您处理大型部署时&#xff0c;即使是那些具有超高密度 NVMe 驱动器的部署&#xff0c;这些服务器上的服务器数量乘以 DRAM 也会迅速增加&#xff0c;通常达到几 TB。该 DR…

【Intel CVPR 2024】通过图像扩散模型生成高质量360度场景,只需要一个语言模型

在当前人工智能取得突破性进展的时代&#xff0c;从单一输入图像生成全景场景仍是一项关键挑战。大多数现有方法都使用基于扩散的迭代或同步多视角内绘。然而&#xff0c;由于缺乏全局场景布局先验&#xff0c;导致输出结果存在重复对象&#xff08;如卧室中的多张床&#xff0…

Android网络性能监控方案 android线上性能监测

1 Handler消息机制 这里我不会完整的从Handler源码来分析Android的消息体系&#xff0c;而是从Handler自身的特性引申出线上卡顿监控的策略方案。 1.1 方案确认 首先当我们启动一个App的时候&#xff0c;是由AMS通知zygote进程fork出主进程&#xff0c;其中主进程的入口就是Ac…

.Net OpenCVSharp生成灰度图和二值图

文章目录 前言一、灰度图二、二值图 前言 使用OpenCVSharp生成图片的灰度图和二值图 .Net 8.0版本&#xff0c;依赖OpenCvSharp4和OpenCvSharp4.runtime.win组件。 原图&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、灰度图 /// &…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 内存访问热度分析(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

Proteus8.13安装及使用

Proteus安装包下载地址 具体安装方法如下&#xff1a; 退出所有杀毒软件,右键以管理员身份运行 如果缺插件安装插件然后点击安装 如果遇到这种需要勾选的都勾选 安装插件完成 安装过程: 安装完成后桌面会自动出现图标 注意这个安装包是免破解的, 安装好以后可以直接使用 打…

竞赛选题 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介 今天学长向大家介绍LSTM基础 基于LSTM的预测算法 - 股票预测 天气预测 房价预测 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

React+TS前台项目实战(十一)-- 全局常用组件提示语可复制Link组件封装

文章目录 前言HighLightLink组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇讲的这个组件&#xff0c;是一个用于高亮显示文本并添加可选的跳转链接&#xff0c;提示文本&#xff0c;复制文本的 React 组件 HighLightLink组件 1. 功能分析 &#x…