文件操作(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;
}

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

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

相关文章

数据结构进阶——AVL树

数据结构进阶——AVL树 0. 前言1. AVL树的概念2. AVL树节点&#xff0c;和树的定义3. AVL树的插入4. AVL树的旋转5. AVL树的验证6. AVL树的删除&#xff08;了解&#xff09;7. AVL树实现完整代码8. AVL树的性能 0. 前言 学习本章&#xff0c;需要大家先掌握搜索二叉树&#xf…

python GUI开发: tkinter事件处理的几种方式详解与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

高考之后,专业与学校如何选择?

随着2024年高考的结束&#xff0c;考生们面临着选择专业或学校的难题。选择专业意味着专注于一个特定领域&#xff0c;直接影响未来的职业发展和兴趣培养&#xff1b;而选择学校则提供了更优越的学术氛围和广泛的社交机会&#xff0c;对个人综合素质提升有重要作用。无论选择哪…

【Linux命令行】从时间管理->文件查找压缩的指令详解

目录 1.date 命令&#xff08;显示时间&#xff09; 1.1 显示方面 1.2 设定时间 1.3 时间戳转换 1.4 cal&#xff08;日历&#xff09; 2. 重定向 2.1 输出重定向&#xff08;echo >&#xff09;cin 2.2 追加重定向 >> 2.3 输入重定向 < cout 3.find 指…

机器学习python实践——关于ward聚类分层算法的一些个人心得

最近在利用python跟着参考书进行机器学习相关实践&#xff0c;相关案例用到了ward算法&#xff0c;但是我理论部分用的是周志华老师的《西瓜书》&#xff0c;书上没有写关于ward的相关介绍&#xff0c;所以自己网上查了一堆资料&#xff0c;都很难说清楚ward算法&#xff0c;幸…

Java小结

# Java的特点 Java是一门面向对象的编程语言。面向对象和面向过程的区别参考下一个问题。 Java具有平台独立性和移植性。 Java有一句口号&#xff1a;Write once, run anywhere&#xff0c;一次编写、到处运行。这也是Java的魅力所在。而实现这种特性的正是Java虚拟机JVM。已…

Dart 弱引用进阶

前言 村里的老人说&#xff1a;“真正的强者&#xff0c;都是扮猪吃老虎。” 日常开发中经常需要用到弱引用&#xff0c;Dart 语言里也有提供弱引用的接口 WeakReference&#xff0c;我们可以基于它开发更强大的复杂结构。 在前面的文章中&#xff0c;我们用到了一个以弱引用…

【笔记】【Git】多个dev分支合并到master分支的文件冲突

问题描述 多个dev分支在同步开发&#xff0c;同时发起代码评审&#xff0c;但合入master的时候存在先后顺序&#xff0c;那么后面同文件的操作则会提示“合并有文件冲突”&#xff0c;导致代码无法入库&#xff0c;只能重新提交。 在个人分支中如何解决与master分支差异&#…

香港优才计划中介避坑,深圳哪家优才中介有实力?

随着香港优才计划取消配额限制以来&#xff0c;优才计划递交申请量骤增&#xff0c;许多DIY的申请人在递交申请后&#xff0c;长时间未能收到审批结果&#xff0c;甚至有人等待了12个月之久仍对审批进展一无所知。 而一些有中介协助的申请人&#xff0c;在等待审批的过程中&am…

通过git命令查询某个用户提交信息

要查询某个用户通过 Git 提交了多少行代码&#xff0c;可以使用以下步骤和命令来实现。这些命令将统计该用户的添加和删除的代码行数。 1、切换到你的 Git 仓库&#xff1a; cd /path/to/your/repositorygit命令结果&#xff1a; 2、查询所有用户&#xff1a; git log --pr…

DPDK环境配置

DPDK环境配置 DPDK&#xff08;Data Plane Development Kit&#xff09;是一个开源的软件框架&#xff0c;最初由Intel开发&#xff0c;旨在提升数据包处理性能&#xff0c;尤其是在Intel架构的处理器上。它允许开发者在用户空间&#xff08;user space&#xff09;而不是传统…

github国内加速访问有效方法

这里只介绍实测最有效的一种方法&#xff0c;修改主机的Hosts文件&#xff0c;如果访问github网站慢或者根本无法访问的时候可以采用下面方法进行解决。 1、搜索一个IP查询网站 首先百度搜索选择一个IP查询的网站&#xff0c;这里我用下面这个网站&#xff08;如果该网站失效…

重新安装TortoiseGit后提示权限错误问题解决

今天在Windows11系统中下载安装使用TortoiseGit可视化Git工具&#xff0c;进行代码提交管理。 由于电脑之前是一位开发人员在使用&#xff0c;所以曾经安装使用过这个工具。 重新安装好软件后&#xff0c;在coding网站中复制代码路径后&#xff0c;在本地目录通过鼠标右键选择…

电影《加菲猫家族》观后感

上周看了电影《加菲猫家族》&#xff0c;本片其中有很多明亮的画面&#xff0c;相关艳丽的色彩&#xff0c;充满温馨的场景&#xff0c;很符合加菲猫的一贯画风&#xff0c;即使反派出场时&#xff0c;带有阴暗的感觉&#xff0c;看起也不是特别吓人&#xff0c;比较欢乐气氛&a…

找不到com.fasterxml.jackson.core.exc.StreamWriteException的类文件

1. 前言: 使用springboot搭建的项目, 需要使用 jackson 更改json文件的内容; maven管理jar包, 导入jar包版本信息如下: <!-- 读写json文件所需依赖 --> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databin…

数据中台-知识图谱平台

【数据分析小兵】专注数据中台产品领域,覆盖开发套件,包含数据集成、数据建模、数据开发、数据服务、数据可视化、数据治理相关产品以及相关行业的技术方案的分享。对数据中台产品想要体验、做二次开发、关注方案资料、做技术交流的朋友们&#xff0c;可以关注我。 1. 概述 随着…

[element-ui]el-select多选选择器选中其中一个选项,不可删除

背景&#xff1a; 产品真的很多奇奇怪怪的需求&#xff0c;一边吐槽一边实现。 前提&#xff1a;选择器作为表格的筛选项&#xff0c;提供三个选项值。 要求&#xff1a;默认选中其中一个值&#xff0c;这个值不可删除。 如图&#xff1a; 小声吐槽&#xff1a;搞这些有什么…

样本学习:当AI遇上“少见多怪”

东汉名臣牟融在其著作《牟子》写道&#xff1a;“少所见&#xff0c;多所怪&#xff0c;睹橐驼&#xff0c;谓马肿背。”意思是见闻少的人遇到不常见的事物就觉得奇怪&#xff0c;见到骆驼也以为是背肿了的马。因此&#xff0c;后人总用“少见多怪”来嘲笑见识浅陋的人。然而&a…

Ps:脚本事件管理器

Ps菜单&#xff1a;文件/脚本/脚本事件管理器 Scripts/Script Events Manager 脚本事件管理器 Script Events Manager允许用户将特定的事件&#xff08;如打开、存储或导出文件&#xff09;与 JavaScript 脚本或 Photoshop 动作关联起来&#xff0c;以便在这些事件发生时自动触…

Excel和Word等工具小技能分享汇编(一)

这里汇集刘小生前期微信公众号分享的Excel和Word等工具小技能&#xff0c;为方便大家查看学习&#xff0c;刘小生对其进行分类整理&#xff0c;后期也会不定期整理更新&#xff0c;如有想学习交流或其他小技巧需求&#xff0c;欢迎留言&#xff0c;我们一起学习进步&#xff01…