新手学习笔记-----⽂件操作

目录

1. 为什么使⽤⽂件?

2. 什么是⽂件?

2.1 程序⽂件

2.2 数据⽂件

2.3 ⽂件名

3. ⼆进制⽂件和⽂本⽂件?

4. ⽂件的打开和关闭

4.1 流和标准流

4.1.1 流

4.1.2 标准流

 4.2 ⽂件指针

4.3 ⽂件的打开和关闭

5. ⽂件的顺序读写

5.1 顺序读写函数介绍

5.1.1 fputc使用举例

1.文件流

2.标准输出流

5.1.2 fgetc使用举例

1.文件流

2. 标准输入流

5.1.3 fputs使用举例

5.1.4 fgets使用举例

5.1.5 fprintf使用举例

1. 文件流

2.标准输出流

5.1.6 fscanf使用举例

5.1.7 fwrite使用举例

5.1.8fread使用举例

5.2 对⽐⼀组函数:

5.2.1 sprintf和sscanf使用举例

6. ⽂件的随机读写

6.1 fseek

1.SEEK_SET

2.SEEK_END

3.SEEK_CUR

6.2 ftell

6.3 rewind

7. ⽂件读取结束的判定

7.1 被错误使⽤的 feof

8. ⽂件缓冲区


1. 为什么使⽤⽂件?

首先,我们使用文件是为了防止数据丢失

一般我们存储数据有2种方式:

1.数据--->内存    退出程序时,数据丢失

2.数据--->硬盘   退出程序时,数据存储在文件中


2. 什么是⽂件?

磁盘上的⽂件是⽂件

⽂件功能的⻆度来分类,一般⽂件有两种:程序⽂件、数据⽂件。

2.1 程序⽂件

程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows环境后缀为.exe)。



2.2 数据⽂件

⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。

一般所处理数据的输⼊输出都是以终端为对象的,即从终端的键盘输⼊数据,运⾏结果显⽰到显⽰器上

其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使⽤,这⾥处理的就是磁盘上⽂件。



如图,这就是键盘输入--->屏幕显示


如图,这就是对数据文件的简单理解

2.3 ⽂件名

⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤

⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀

注意⚠️

文件后缀可以自己设计,但是要注意一些常用的后缀名

例如: c:\code\test.txt

为了⽅便起⻅,⽂件标识常被称为⽂件名。

3. ⼆进制⽂件和⽂本⽂件?

组织形式的⻆度来分类,一般⽂件有两种:二进制文件,文本文件

数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存,就是⼆进制⽂件

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂本⽂件

⼀个数据在内存中是怎么存储的呢?

字符⼀律以ASCII形式存储数值型数据既可以⽤ASCII形式存储,也可以使⽤⼆进制形式存储。

下面我们以10000的存储来举例:


下面我们在VS上测试一个代码试试看:

#include <stdio.h>
int main()
{int a = 10000;FILE* pf = fopen("test.txt", "wb");//⼆进制的形式写到⽂件中fwrite(&a, 4, 1, pf);//将a内存中的1个4个字节的数据写到pf管理文件test.txt中fclose(pf);pf = NULL;return 0;
}

我们发现在生成的文件中打开的看不懂,接下来怎么办?


4. ⽂件的打开和关闭

4.1 流和标准流

4.1.1 流

操作文件顺序:

1.打开文件(流)

2.读/写文件

3.关闭文件

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同为了⽅便程序员对各种设备进⾏⽅便的操作我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。

C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是同流操作的

⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作

4.1.2 标准流

那为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢?

那是因为C语⾔程序在启动的时候,默认打开了3个流

• stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊。

• stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯。

• stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。

这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。

stdin、stdout、stderr三个流的类型是: FILE* ,通常称为⽂件指针。

C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。


 4.2 ⽂件指针

使用文件,打开文件--->打开的同时,创建一个对应的文件信息区--->信息保存在FILE类型的结构变量中

⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使⽤起来更加⽅便

FILE* pf;//⽂件指针变量

使pf指向某个⽂件的⽂件信息区,通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件。


4.3 ⽂件的打开和关闭

⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。

ANSIC 规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。

//打开⽂件
FILE * fopen ( const char * filename, const char * mode );//文件名              //打开方式
//关闭⽂件
int fclose ( FILE * stream );


如图,这样我们就方便理解什么是输入什么是输出了。

接下来我们看看mode对应的表:


/* fopen fclose example */
#include <stdio.h>
int main ()
{//打开⽂件FILE * pFile = fopen ("myfile.txt","w");//判断if(pFile==NULL)
{perror("open");return 1;
}//⽂件操作//......//关闭⽂件fclose (pFile);return 0;
}

如果要打开的文件不在代码的路径底下,而是像在桌面的话,怎么办打开桌面的文件呢?

1.绝对路径


2.相对路径(相对于当前路径的位置)


5. ⽂件的顺序读写

5.1 顺序读写函数介绍


5.1.1 fputc使用举例


1.文件流

运行成功


2.标准输出流


5.1.2 fgetc使用举例


1.文件流


2. 标准输入流


5.1.3 fputs使用举例



5.1.4 fgets使用举例



不过,为什么我们不加\n换行呢?又为什么说只能打印(n-1)个数据呢?


5.1.5 fprintf使用举例


1. 文件流


2.标准输出流


5.1.6 fscanf使用举例



5.1.7 fwrite使用举例



但是,由于是二进制的输出我们无法观察,所以,我们尝试以二进制的方式输入读取

5.1.8fread使用举例



5.2 对⽐⼀组函数:

scanf/fscanf/sscanf

printf/fprintf/sprintf

scanf--->针对标准输入流(stdin)的格式化输入函数

printf--->针对标准输出流(stdout)的格式化输出函数

fscanf--->针对所有输入流的格式化输入函数

fprintf--->针对所有输出流的格式化输出函数

sscanf--->从字符串中读取格式化的数据

sprintnf--->把格式化的数据转换成字符串



5.2.1 sprintf和sscanf使用举例


然我们仔细看看:

1.格式化的数据确实转化成字符串存放到arr中了

2.确实从字符串中读取了格式化的数据


6. ⽂件的随机读写

6.1 fseek

根据⽂件指针的位置和偏移量来定位⽂件指针。


例如,我在文件中写abcdefghijk;现在想读取g

1.SEEK_SET


2.SEEK_END


3.SEEK_CUR


6.2 ftell

返回⽂件指针相对于起始位置的偏移量



6.3 rewind

让⽂件指针的位置回到⽂件的起始位置



7. ⽂件读取结束的判定

7.1 被错误使⽤的 feof

牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束

feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束。

1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )

例如:

 fgetc 判断是否为 EOF .

• fgets 判断返回值是否为 NULL .

2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数

例如:

• fread(fread返回的是实际读取到的元素个数)判断返回值是否⼩于实际要读的个数。

例如共有14个数据,每次读取4个,

4,4,4,2,

最后一次实际读取的个数小于要求读取的个数

⽂本⽂件的例⼦:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{int c; // 注意:int,⾮char,要求处理EOFFILE* fp = fopen("test.txt", "r");if(!fp) {perror("File opening failed");return EXIT_FAILURE;}//fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环{ putchar(c);}//判断是什么原因结束的if (ferror(fp))puts("I/O error when reading");else if (feof(fp))puts("End of file reached successfully");fclose(fp);return 0;
}

⼆进制⽂件的例⼦:

#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{double a[SIZE] = {1.,2.,3.,4.,5.};FILE *fp = fopen("test.bin", "wb"); // 必须⽤⼆进制模式fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组fclose(fp);double b[SIZE];fp = fopen("test.bin","rb");size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组if(ret_code == SIZE) {puts("Array read successfully, contents: ");for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]);putchar('\n');}else { // error handlingif (feof(fp))printf("Error reading test.bin: unexpected end of file\n");else if (ferror(fp)) {perror("Error reading test.bin");}}fclose(fp);return 0;}

8. ⽂件缓冲区

ANSIC 标准采⽤“缓冲⽂件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的。


#include<stdio.h>
#include <windows.h>
//VS2022 WIN11环境测试
int main()
{FILE*pf = fopen("test.txt", "w");fputs("abcdef", pf);//先将代码放在输出缓冲区printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");Sleep(10000);//单位是毫秒printf("刷新缓冲区\n");fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)//注:fflush 在⾼版本的VS上不能使⽤了printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");Sleep(10000);fclose(pf);//注:fclose在关闭⽂件的时候,也会刷新缓冲区pf = NULL;return 0;
}

本次的分享到这里就结束了!!!

PS:小江目前只是个新手小白。欢迎大家在评论区讨论哦!有问题也可以讨论的!

如果对你有帮助的话,记得点赞👍+收藏⭐️+关注➕

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

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

相关文章

node版本问题:Error: error:0308010C:digital envelope routines::unsupported

前言 出现这个错误是因为 node.js V17及以后版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制&#xff0c;可能会对生态系统造成一些影响. 在node.js V17以前一些可以正常运行的的应用程序,但是在 V17 及以后版本可能会抛出以下异常: 我重装系…

【Vue组件化编程】

Vue组件化编程 1 对组件的理解2 非单文件组件2.1 基本使用2.2 几个注意点2.3 组件的嵌套2.4 VueComponent构造函数2.5 一个重要的内置关系 3 单文件组件 1 对组件的理解 组件&#xff1a;实现应用中局部功能代码和资源的集合。优点&#xff1a;文件好维护&#xff1b;依赖关系不…

DP读书:《openEuler操作系统》(四)鲲鹏处理器

鲲鹏处理器 一、处理器概述1.Soc2.Chip3.DIE4.Cluster5.Core 二、体系架构1.计算子系统2.存储子系统3.其他子系统 三、CPU编程模型1.中断与异常2.异常级别a.基本概念b.异常级别切换 下面为整理的内容&#xff1a;鲲鹏处理器 架构与编程&#xff08;一&#xff09;处理器与服务器…

虹科分享 | 为工业机器人解绑,IO-Link wireless无线通讯技术可实现更加轻量灵活的机器人协作

背景 机器人是一种能够半自主或全自主工作的智能机器。中国电子学会组织发布的《中国机器人产业发展报告&#xff08;2022年&#xff09;显示&#xff0c;近些年&#xff0c;我国机器人市场规模持续快速增长&#xff0c;“机器人”应用不断拓展深入&#xff0c;预计五年年均增…

美团外卖优惠券小程序 美团优惠券微信小程序 自带流量主模式 带教程

小程序带举牌小人带菜谱流量主模式&#xff0c;挺多外卖小程序的&#xff0c;但是都没有搭建教程 搭建&#xff1a; 1、下载源码&#xff0c;去微信公众平台注册自己的账号 2、解压到桌面 3、打开微信开发者工具添加小程序-把解压的源码添加进去-appid改成自己小程序的 4、…

利用抽象工厂模式提升游戏开发的精度与灵活性

引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》&#xff0c;让糟糕的代码在潜移默化中升华&#xff0c;欢迎大家关注分享收藏订阅。 在开发过程中&#xff0c;如何有效地管理各种游戏对象并…

【RP-RV1126】烧录固件使用记录

文章目录 烧录完整固件进入MASKROM模式固件烧录升级中&#xff1a;升级完成&#xff1a; 烧录部分进入Loader模式选择文件切换loader模式 烧录完整固件 完整固件就是update.img包含了所有的部件&#xff0c;烧录后可以直接运行。 全局编译&#xff1a;./build.sh all生成固件…

linux——信号

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——进程等待 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;生活中处处有信号&#xff0c;linux中也有很多信号&#xff0c;OS使…

YOLOv5、YOLOv8改进:RepVGG结构

1.简介 论文参考&#xff1a;最新RepVGG结构: Paper 我们所说的“VGG式”指的是&#xff1a; 没有任何分支结构。即通常所说的plain或feed-forward架构。 仅使用3x3卷积。 仅使用ReLU作为激活函数。 主要创新点为结构重参数化。在训练时&#xff0c;网络的结构是多分支进…

虚拟机通过nat模式端口映射实现内网穿透

虚拟机通过nat模式端口映射实现内网穿透 1.网络状态 windows虚拟主机的IP为局域网的私有IP192.168.1.7linux的虚拟主机IP为nat的172.36.4.1062.linux修改nat模式的端口映射 3.windows宿主机防火墙添加规则,&#xff08;或者直接关闭公共网络防火墙&#xff0c;不安全&#xf…

『力扣每日一题12』:只出现一次的数字

一、题目 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用常量额外空间。 示例 1 &#xff1a; 输入&…

笔记一:odoo透视表和图表

透视表 1、首先在xml文件添加pivot 说明&#xff1a;&#xff08;1&#xff09;根元素pivot中属性&#xff1a; disable_linking&#xff1a;设置为True&#xff0c;删除表格单元格到列表视图的链接 display_quantity&#xff1a;设置为True&#xff0c;默认显示“数量”列 d…