当前位置:首页 » 《随便一记》 » 正文

超详细的文件操作讲解

16 人参与  2023年05月02日 17:45  分类 : 《随便一记》  评论

点击全文阅读


各位朋友们,大家好啊,今天我要分享的是关于文件操作方面的知识。

文章目录

为什么会有文件操作什么是文件文件操作文件指针文件的打开与关闭fopen(打开文件)fclose(关闭文件) 打开文件的方式文件的顺序读写fgets函数fputc函数fgets函数fputs函数fprintf函数fscanf函数 文件的非顺序读写fseek函数ftell函数rewind函数 二进制读写fwrite函数`fread函数 结语

为什么会有文件操作

那么大家可能会问:为什么会有文件操作呢?前面我们可能都了解了通讯录,我们知道当我们使用通讯录的时候我们可以添加联系人,也可以删除联系人,但是当我们退出程序之后下次再进来的时候,我们要想看看通讯录里面有那些联系人,我们打开通讯录发现里面是空的,这是为什么呢?因为我们这种通讯录实在内存上操作的,当我们关闭程序或者关机的时候,这些内存就会被释放掉了,那么我们想要下次打开通讯录的时候,里面的内容还在的话,我们就需要使用文件来操作了。

什么是文件

文件通常是指磁盘上的文件,就像我们平时购买电脑的时候我们可能会买16+512的,这个16通常是指运行内存,我们写代码的时候通常使用的就是这个内存,而我们安装QQ、微信啊这些就是安装在磁盘上的,这些数据不会随着你电脑关机或者没电的时候而消失,他会一直存在,除非你故意删除或者磁盘损坏。所以我们使用文件来操作可以将数据存储在磁盘上保存。

文件又分为程序文件文件和内存文件。他们分类的依据是根据功能来分类的,不知道你们是否发现了,当我们写了一个代码并编译运行的时候,我们可以在我们项目的文件路径下发现.obj后缀和.exe后缀的文件,这些等等都属于程序文件,而当我们程序运行的时候读取的文件称为数据文件。

那么我们知道了什么是文件以及使用文件的好处了之后,我们来学习怎样进行文件操作。

文件操作

文件指针

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE。也就是说我们需要使用FILE来找到文件的地址,并对其进行相关操作。其实这就跟普通指针差不多,就像int* p = &a,一样*说明他是一个指针变量,而int说明这个指针指向的是int类型的数据,FILE也是如此。

文件的打开与关闭

当我们使用文件的时候我们需要在知道使用的步骤,就像我们想要在冰箱里面拿东西一样,我们首先需要打开冰箱,然后我们可以从冰箱里面拿出东西也可以往冰箱里面放东西,我们进行文件操作的时候也是先打开文件,然后进行相关操作,最后就是关闭文件。

fopen(打开文件)

FILE * fopen ( const char * filename, const char * mode );

const char* filename是我们要打开的文件地址,const char* mode是我们以怎样的形式打开。

fclose(关闭文件)

int fclose ( FILE * stream );

FILE * stream是我们需要关闭的文件地址,这里我们需要注意的是fclose并不会将要关闭的文件置为NULL,所以我们需要手动置空。

接下来我们就来看看有哪些打开文件的方式吧。

打开文件的方式

在这里插入图片描述
我们在使用的时候可以根据需要以不同的方式打开。我们举个例子:
首先我们在我们的项目路径下创建一个test.txt文档,用来做测试。
在这里插入图片描述
然后我们在这个文档里面写入内容。
在这里插入图片描述

#include<stdio.h>int main(){//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");}//进行相关文件操作//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述
我们这里就是以读的形式打开的。

文件的顺序读写

在这里插入图片描述
这里的流是什么意思呢?其实这个流只是一个抽象概念,就像一条河流,当我们需要灌溉农田的时候我们就可以用抽水机来抽取。我们的键盘和屏幕实际上也是一个文件,我们的电脑从键盘中读取数据,然后将数据显示到屏幕上,键盘也叫标准输入流(stdin),屏幕叫做标准输出流(stdout)。

那么我们来举几个例子来看看这写函数是什么作用吧。

fgets函数

char * fgets ( char * str, int num, FILE * stream );
#include<stdio.h>int main(){//打开文件FILE* pf = fopen("test.txt", "r");char arr[10] = { 0 };if (pf == NULL){perror("fopen");return 0;}//进行相关文件操作fgets(arr, 5, pf);printf("%s", arr);//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述
虽然我们在这里想要读取5个元素,但是其实只读取了4个元素,因为最后一个元素要读取’\0’。

fputc函数

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

我们先将前面的文档里面的内容删除。
在这里插入图片描述

#include<stdio.h>int main(){FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写文件//把26个字母写到文件中int i = 0;for (i = 0; i < 26; i++){fputc('a'+i, pf);}//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述

fgets函数

char * fgets ( char * str, int num, FILE * stream );

fgets可以读取一行的数据

#include<stdio.h>int main(){FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读char arr[20];fgets(arr, 5, pf);printf("%s\n", arr);//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述

fputs函数

fputs写一行的数据

int fputs ( const char * str, FILE * stream );
#include<stdio.h>int main(){FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("hello bit", pf);//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述

fprintf函数

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

后面的省略号说明你自己可以定义长度。

#include<stdio.h>struct S{int n;float f;char arr[20];};int main(){struct S s = { 100, 3.14f, "zhangsan" };//打开文件FILE* pf = fopen("test.txt", "w");if (NULL == pf){perror("fopen");return 1;}//写文件fprintf(pf, "%d %f %s\n", s.n, s.f, s.arr);//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述

fscanf函数

int fscanf ( FILE * stream, const char * format, ... );
#include<stdio.h>struct S{int n;float f;char arr[20];};int main(){struct S s = {0};//打开文件FILE* pf = fopen("test.txt", "r");if (NULL == pf){perror("fopen");return 1;}//读文件fscanf(pf, "%d %f %s", &(s.n), &(s.f), s.arr);printf("%d %f %s\n", s.n, s.f, s.arr);//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述
那么前面的都是顺序读写,但是当我们想要在任意位置写的时候我们又该怎么办呢?
我们这就得用到fseek函数和ftell函数了,这两个函数可以随机读写文件。

文件的非顺序读写

fseek函数

int fseek ( FILE * stream, long int offset, int origin );

stram还是我们需要读取的文件的地址,offset 是相对于origin的偏移量,origin有三种不同的形式。SET表示文件的开始位置,CUR表示文件指针的当前位置,END表示文件的结尾。
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>int main(){FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen file");return 1;}for (int i = 0; i < 5; i++){fgetc(pf);}//现在pf文件指针已经向后移动了5个字节,现在我们想要读取的元素是b,b与文件首元素的地址的偏移量是1fseek(pf, 1, SEEK_SET);int a = fgetc(pf);printf("%c", a);fclose(pf);pf = NULL;return 0;}

在这里插入图片描述

ftell函数

long int ftell ( FILE * stream );

ftell函数返回的是你当前的文件指针与文件开始的地址处的偏移量,这里我就不需要过多解释了。

rewind函数

void rewind ( FILE * stream );

这个函数的作用是让文件指针回到文件的起始位置

二进制读写

fwrite函数`

fwrite函数是针对二进制来说的,他写入的形式是以二进制来写的。

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

这个函数返回的是你写入的字符的个数,参数一个是ptr,代表的是从哪写入,一个是size,表明要写入的内容的大小,count是指要写入多少个这样的内容,stream是你要写入那个文件中。

#include<stdio.h>struct S{int n;float f;char arr[20];};int main(){struct S s = { 10,3.14f,"hello" };FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}fwrite(&s, sizeof(struct S), 1, pf);fclose(pf);pf = NULL;return 0;}

在这里插入图片描述
这样我们可能看不懂吧,因为这是以二进制的形式写入的,所以我们并不能看懂。

fread函数

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
#include <stdio.h>struct S{char name[20];int age;float score;};int main(){struct S s = {0};FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}//读文件fread(&s, sizeof(struct S), 1, pf);printf("%s %d %f\n", s.name, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;}

在这里插入图片描述

结语

那么这些就是我学到的关于文件操作的只是,感谢大家的观看,如有错误,请随时订正。


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/60268.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1