前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【c语言】巨巨巨详细!—— 文件操作(笔记整理)

【c语言】巨巨巨详细!—— 文件操作(笔记整理)

作者头像
用户11292525
发布2024-09-26 11:04:34
860
发布2024-09-26 11:04:34
举报
文章被收录于专栏:学习

一.文件是啥东东?

标啊题

   想必我们日常用电脑经常打开各种各样的文件,会用,但具体形容一下....

“啊?不就是..文件吗?鼠标点开那个...”

——想必会如这般语塞吧

这不得证明一下咱可是程序员,讲的专业点 咳 进入正题

        1. 使用文件的原因

       很早使用计算机的老前辈想将写的程序的数据存储在电脑的内存中,但是,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的。

    于是老前辈脑瓜子一转,如果要将数据进⾏持久化的保存,搞个叫⽂件的东西存着就好了。

     放到现在,咱都知道,磁盘(硬盘)上的⽂件是⽂件。

     但是在咱敲代码的眼中,我们⼀般谈的⽂件,按功能分有两种:程序⽂件、数据⽂件

        2. 程序文件

                               包括  源程序⽂件(后缀为.c),

                                        ⽬标⽂件(windows环境后缀为.obj),

                                        可执⾏程序(windows 环境后缀为.exe)。

        3. 数据文件

       也就是程序运⾏时读写的数据——比如程序运⾏需要从中读取数据的文件,或者输出内容的文件。

      说的俗一点,就是咱看小说下载的那些个以.txt为后缀的东西。

      这篇笔记记的也是这玩意。

二.如何在程序设计中文件的打开和关闭

    用鼠标对电脑里的文件图标点击打开谁都会吧,有手就行,这个打开关闭就不用多说了。

    咱重点说说用敲代码的方式,对文件进行打开关闭。

把大象关进冰箱需要几步呢?       三步——打开冰箱门,把大象放进去,关上冰箱门。

同样的,读写文件也是——

      打开文件 → 读/写文件内容 → 关闭文件

(一)打开文件——fopen函数

1.文件指针——读写文件的“鼠标光标”

首先,我们需要一个能帮我们定位输入输出文件内容的工具。

每当打开⼀个⽂件的时候,系统会根据⽂件的情况⾃动创建⼀个FILE结构体的变量(这个结构体里面有文件名,文件位置等文件相关信息),需要我们⼀个FILE的指针来维护这个FILE结构的变量。

在我的个人理解里,他像一个编辑定位的鼠标光标,它可以指向某个文件的文件信息区,通过其即可访问到该文件。

笔的使用方式:

代码语言:javascript
复制
FILE* pf
2.打开文件——用指针使代码程序与文件建立联系

基本使用方式:

代码语言:javascript
复制
    FILE* pf= fopen("文件名","使用方式(是读还是写还是别的)");

	if (pf == NULL)   //防止出现野指针
	{
		perror(fopen);
		return 1;
	}

其中 文件名如“text.txt” , 使用方式如下

文件使用方式

(二)读/写文件内容

读写文件运用到的函数如下:

具体函数的使用实操 
顺序读写
1.fputc——写入一个字符:
代码语言:javascript
复制
    fputc('a', pf);

得到结果如图

2.fgetc——读取一个字符(两种使用):
代码语言:javascript
复制
    //读取一个字符
    int ch = fgetc(pf);
    if (ch != EOF)
    {
        printf("%c\n", ch);
    }



   //连续每次读取一个字符

    //文件中有qwertyu
 
    int ch = fgetc(pf);
    printf("%c\n", ch);    //q
    ch = fgetc(pf);
    printf("%c\n", ch);    //W
    ch = fgetc(pf);
    printf("%c\n", ch);    //e
    ch = fgetc(pf);
    printf("%c\n", ch);    //r

第一段代码得到结果如图

3.fputs——覆盖并写入一行字符串数据:
代码语言:javascript
复制
  fputs("hahahaha", pf);

这里需要注意的是,如上面3.中原“text.txt”文件内容是qwertyu,但是我们fputs函数比较霸道,每次写入都会把原来的内容覆盖了

原文件内容:

使用fputs后的文件内容

4.fgets——读取指定长度的一行字符串数据(两种使用)

原文件内容

我们需要创建一个数组来存放一定长度的数据, 然后将所读取的数据放入arr中。

第二段代码中,通过while循环将读取到“鼠标光标”指向数据末尾,也就是读完了。

代码语言:javascript
复制
//读文件指定长度的数据
	char arr[10] = { 0 };
	fgets(arr, 5, pf);   
	printf("%s\n", arr)

//读文件全部数据
	char arr[20] = { 0 };
	while (fgets(arr, 20, pf) != NULL)
	{
		printf("%s", arr);
	}

第一段代码结果如下 值得一提的是,fgets函数读完的结果一定会留最后一个数据给\0 (也就是读5个指定长度,它只读了4个长度,最后一个长度给\0.)

第二段代码结果

5.fprintf——将结构体信息写入文件

这里的fprintf也就比printf多了一个要连接文件与程序文件之间的“笔”——pf

其格式大致为

代码语言:javascript
复制
fprintf(文件指针名,"占位符",要赋值的变量/结构体变量)
对比一下
printf("占位符",要赋值的变量)
6.fscanf——从文件中读取数据内容放到结构体中

同5类似,其格式大致如下

代码语言:javascript
复制
fscanf(文件指针名,"占位符",&赋值的变量/结构体变量)
对比一下
scanf("占位符",&要赋值的变量)
特别提醒点:

上述的输入——写和输出——读的函数 不仅可以在文件里生效,也可以在程序中像printf或者scanf那样使用

  如6中的打印结构体内容

这里我个人理解为,其与printf的区别就是多了个需要笔的工具,这里的笔用stdout代替。

输出的”笔“是stdout,而输入的”笔“则是stdin

7.sprintf函数和sscanf函数

因为提到了fprintf和fscanf,干脆也去学了sprintf和sscanf。

如果说,printf是直接把数据打印在程序上

fprintf是把数据拿了支笔打印在程序上,

那sprintf则是直接把数据从结构体上拿起来,转化成字符串(以字符串打印在字符串数组char上)。

此时的arr每个元素中分别以单个字符的形式存储了结构体的数据,变成一串字符串。

同理,sscanf函数运用便是将一个字符串转化成结构体的数据

此时的结构体b中就包含了数组arr的数据内容。

8.fwrite——以二进制的形式写入文件数据

基本书写格式

代码语言:javascript
复制
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream )

       fwrite(要写的数据, 单个数据的长度, 数据元素的个数, 对应的文件指针)

注意打开文件那块用的是”wb“!!

此时你打开文件,就会看见一堆你根本看不懂,但是是二进制的形式的数据内容。

9.fread——读取文件内的二进制数据

同理 fread的基本格式

代码语言:javascript
复制
size_t fread( void *buffer, size_t size, size_t count, FILE *stream )

       fread(要写的数据, 单个数据的长度, 要读取的数据元素个数, 对应的文件指针)

这时你去打印数组的内容,呈现在程序上的是整型的数据,而不是二进制

随机读写
1.fseek——使文件指针读取指定我们想要读写的位置

假定我们要读这个数

实操分析: 

 完整代码如下:

代码语言:javascript
复制
​
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//运用fseek函数读文件中第五个元素的数据
	//我们指定初始位置、当前文件指针所处位置、末尾位置三个不同的角度来指定位置同个数据的读取
	

	//从头开始读取向后4个偏移量的位置的数据
	fseek(pf,4,SEEK_SET);
	//打印字符看看是否读取成功
	int ch = fgetc(pf);
	fprintf(stdout, "%s\n", ch);

	//从当前位置(此时当前文件所处位置在第二元素处)向后读取3个偏移量来读取数据
	fseek(pf,3, SEEK_CUR);
	ch = fgetc(pf);
	fprintf(stdout, "%s\n", ch);

	//文件末尾读取向前6个偏移量的位置的数据
	fseek(pf,-6, SEEK_END);
	ch = fgetc(pf);
	fprintf(stdout, "%s\n", ch);

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

	return 0;
}

​
2.ftell函数——返回初始位置到当前位置的偏移量

有时候文件读取多了,读着读着咱就读迷糊了,不知道这个文件指针移动到啥位置了,据初始位置有多远,这个时候咱就可以用这个瞅瞅指针走了多远的距离。

具体用法

代码语言:javascript
复制
 long int ftell ( FILE * stream )

如上笔记中的pf作为我们文件指针名
具体使用则: ftell(pf)

此时比如文件指针读到1.中的 t的 位置 ,其离初始位置偏移量为4,则该函数返回值为4。

2.rewind函数——让文件指针回到文件初始位置

引用王者花木兰的话:“离家太远会忘记故乡...”,咱文件读多了,又不小心迷糊了,想让文件指针回家从头来,这时候就运用到rewind函数啦~

具体用法

代码语言:javascript
复制
void rewind ( FILE * stream )

如在上述例子中
我们使用则: rewind(pf)

(三)关闭文件——fclose函数

基本使用方式

代码语言:javascript
复制
    fclose(pf);
	pf = NULL; //防止pf变成野指针

三.判断文件是否结束【误区】

文件读取结束有两种原因: ①文件读取到末尾啦 ②文件读取出现异常错误 这俩种情况分别需要两种不同的函数来判断! ①ferrror函数——判断是否文件读取异常错误而结束; ②feof函数——判断是否文件正常读取到尾而结束;

如下,我们实操书写一个错误来具体分析使用这俩个函数,以此判断是否结束 

四.实操应用(同时读写文件):将文件1的内容拷贝到文件2去 

现在基础都会了,但是能用他来干什么呢?

这里提供一个实操的例子:拷贝文件:test1.txt  ——>  test2.txt

五.【我的疑问】二进制存储文件的好处——大佬的解释

我们知道数据在内存中是以二进制形式存储的。 对于文件而言:如果不加转换直接输出到外存就是二进制文件;                          如果要在外存上以ASCII码形式存储,就需要提前转换最后以ASCII码值形式存储的文件就是文本文件。 我的疑惑:为什么读写文件还有二进制的形式?这个用二进制形式的函数都有什么作用呢?  二进制文件存储相比于文本文件存储而言,有什么更好的地方吗?

几经网上查找和询问,我的疑惑终于得到了解答。

这里我直接引用CSDN的其他大佬的博客的解释

到这里,诸位看官觉得如何?

呜呜我我我应该不会原地胖十斤把QAQ... 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.文件是啥东东?
    •         1. 使用文件的原因
      •         2. 程序文件
        •         3. 数据文件
        • 二.如何在程序设计中文件的打开和关闭
          • (一)打开文件——fopen函数
            • 1.文件指针——读写文件的“鼠标光标”
            • 2.打开文件——用指针使代码程序与文件建立联系
          • (二)读/写文件内容
            • 具体函数的使用实操 
            • 顺序读写
            • 随机读写
          • (三)关闭文件——fclose函数
          • 三.判断文件是否结束【误区】
          • 四.实操应用(同时读写文件):将文件1的内容拷贝到文件2去 
          • 五.【我的疑问】二进制存储文件的好处——大佬的解释
          相关产品与服务
          文件存储
          文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档