文件操作(总)

1.为什么使用文件

     

a是内存上的一块区域

如果程序退出,则内存回收,数据丢失了,再次运行就看不到上次的数据了

为了持久化保存,我们可以使用文件

2.文件是什么

磁盘上的文件是文件

在程序设计中,文件有两种:程序文件,数据文件

2.1程序文件

1)源文件(.c)

2)目标文件(windows环境后缀为.obj)

3)可执行程序(windows环境后缀为.exe)

2.2数据文件(这里讨论的就是这种)

文件的内容不一定是程序,而是程序运行时读写的数据

如:程序运行需要从中读取数据的文件,或者输出内容的文件

以前所处理的数据的输入输出都是以终端为对象的(从终端的键盘输入数据),运行结果显示到显示器上

我们也会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件

2.3文件名

文件名就是文件标识

文件名包含三部分:文件路径+文件名主干+文件后缀

eg.   c:\code\text.txt

                           

3.根据数据的形式,数据文件被称为文本文件或者二进制文件

二进制文件:

                     数据在内存中以二进制的形式存储,不加转换地输出到外存

文本文件:   

                    如果要求在外存上以ASCII码的形式存储,就需要在存储前转换

                    以ASCII字符的形式存储的文件就是文本文件

一个数据在内存中的存储

字符一律使用ASCII形式存储

数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储

测试:

4.文件的打开和关闭

4.1流

流包含各种流,标准流只是一种

我们可以把"流"想象成流淌着字符的河

C程序`针对文件,画面,键盘等的数据输入输出操作都是通过流操作的

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

4.2标准流

我们从键盘输入数据,向屏幕上输出数据并没有打开流的原因是因为C语言程序在启动的时候默认打开了三个流

1)stdin - 标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准流中读取数据

2)stdout - 标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中

3)stderr - 标准错误流,大多数环境中输出到显示器界面

默认打开了这三个流,我们使用scanf,printf等函数就可以直接进行输入输出操作

三个流的类型是:FILE*,成为文件指针(痛过文件指针找到流,通过流的操作再操作对应的外部设备)

                三个流就是指向文件信息区的指针

scanf读取数据时并没有打开流,直接在标准输入流中读取数据

printf直接输出信息输出到stdout对应的流里面

对于程序来说,文件,光盘,U盘等这些是外部设备

4.3文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”

每个被使用的文件都在文件中开辟了一个相应的文件信息区,用来存放文件的相关信息(文件的名字,文件状态及文件当前的位置),这些信息是保存在一个结构体变量中的,该结构体类型是由系统声明的

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不用关系细节

一般都是通过一个FILE的指针来维护这个FILE结构的变量

文件信息区和将要操作的文件进行关联,想要实现这个就要拿到指向文件信息区的这个指针

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

pf是一个指向FILE类型数据的指针变量,可以使pf指向某个文件的文件信息区(是一个结构体变量),通过该文件信息区中的信息就能访问该文件,也就是说通过文件指针变量能够间接找到与它关联的文件

文件在硬盘里存放                     文件信息区在内存存放

4.4 文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系

打开文件

fopen

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

                                 文件名                            文件的打开方式

mode:

文件的使用方式:      含义   :                                              如果指定文件不存在:

r”(只读)   为了输⼊数据,打开⼀个已经存在的⽂本⽂件   出错
“w”(只写) 为了输出数据,打开⼀个⽂本⽂件                     建⽴⼀个新的⽂件
“a”(追加) 向⽂本⽂件尾添加数据                                       建⽴⼀个新的⽂件
“rb”(只读)为了输⼊数据,打开⼀个⼆进制⽂件                 出错
“wb”(只写  为了输出数据,打开⼀个⼆进制⽂件                 建⽴⼀个新的⽂件
“ab”(追加)向⼀个⼆进制⽂件尾添加数据                           建⽴⼀个新的⽂件
“r+”(读写) 为了读和写,打开⼀个⽂本⽂件                       出错
“w+”(读写)   为了读和写,建议⼀个新的⽂件                      建⽴⼀个新的⽂件
“a+”(读写)  打开⼀个⽂件,在⽂件尾进⾏读写                  建⽴⼀个新的⽂件
“rb+”(读写) 为了读和写打开⼀个⼆进制⽂件                     出错
“wb+”(读写) 为了读和写,新建⼀个新的⼆进制⽂件           建⽴⼀个新的⽂件
“ab+”(读写) 打开⼀个⼆进制⽂件,在⽂件尾进⾏读和写  建立一个新的文件

 如果这个文件不存在,则会新建一个文件,如果存在,他会把文件里面的内容清空

运行后

关闭文件

fclose

int  fclose ( FILE * stream);

相对:

5.文件的读和写

以读的形式打开文件,就只能读

以写的形式打开文件,就只能写

                                                                            stdin -- 标准输入流

                                                                           的形式打开文件--得到的是一个文件的输入流 

                                                                            stdout

                                                                           的形式打开文件--得到的是文件的输出流

                        

文件的顺序读写

函数名                   功能                                                    适用于

fgetc                字符输⼊函数  ( 字符)                    所有输⼊流
fputc                 字符输出函数  ( 字符)                    所有输出流
fgets                 ⽂本⾏输⼊函数(读字符串)               所有输⼊流              读和写的都是文本信息
fputs                 ⽂本⾏输出函数 (写字符串)              所有输出流
fscanf               格式化输⼊函数                                     所有输⼊流
fprintf               格式化输出函数                                     所有输出流
fread                ⼆进制输⼊                                           ⽂件
fwrite                二进制输出                                           文件                            二进制信息

fputc(将字符写到流里面去)

int  fputc ( int  character , FILE  *  stream );
                    要写的那个字符

fgetc

int  fgect  (  FILE  *  stream  );
读取正常的时候,返回读取到的字符的ASCII码值
读取失败的时候,会返回EOF
EOF的本质是end  of  file
文件的结束标志

fputs

把一个字符串写到文件里面去(写的时候要自己写'\0',不然文件里面的内容都是在一行上的)

首字符的地址

fgets

从FILE*指向的文件流里去读字符串

区分放进去的还是不放进去的

实际上真正读的是n-1个字符再加上'\0'

如果修改文件内容,在字符串中添加'\0',则读的时候遇到'\0'就不读了(但是'\0'还是会有),也不会再读下一行(即使没有达到字符个数)

解释:如果num=10;

这一行超过10个字符则读九个再加一个'\0',如果不超过9个就换行了,则读到'\0'就停下来了

fwrite

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

将ptr中count个大小为size个字节(一个元素的大小)的数据写到文件中

(在流里面写count个size大小的数据到ptr指向的空间里面)

fread

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

成功读取几个元素返回几个;小于count则为最后一次了

从文件中读取count个大小为size个字节的数据,存放在ptr指向的空间中

对比一组函数

scanf/fscanf/sscanf

scanf     针对标准输入流的格式化输入函数

int  scanf  (  const  char  *  format, ... ) ;   可变参数列表                                                             

                                                                                   

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

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

 

sscanf   将格式化的数据转换成字符串

int  sscanf  (  const  char  *  s, const  char  *  format ,...   ) ;

printf/fprintf/sprintf

printf        针对标准输出流得格式化输出函数     

int  printf ( const  char  *  format , ... ) ;

fprintf       针对所有输出流的格式化输出

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

sprintf        是从字符串中提取格式化的数据

                  可以理解为,将字符串转成格式化的数据

int  sprintf (  char  *  str  , const char  *  format  ,... ) ;

6.文件的随机读写

fseek

根据文件指针的位置和偏移量来定位文件指针(根据需要调整指针的位置)

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

                                                偏移量                起始位置

SEEK_SET           文件的起始位置

SEEK_CUR          文件指针当前的位置

SEEK_END           文件的末尾

ftell

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

long  int  ftell ( FILE * stream ) ;

rewind

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

拷贝文件

7.文件读取结束的判定

EOF   --    end  of  file    文件结束的标志

以为feof函数是用来判断文件是否结束的

但是并不是

在读取文件的过程中,有可能读取文件错误

原因:

1.遇到文件末尾

2.遇到错误

文本文件:

fgetc  读取失败会返回EOF

fgets  读取失败或遇到文件末尾会返回空指针

二进制文件:

fread  判断返回值是否小于实际要读的个数

小于count则为最后一次了

8.文件缓冲区

所谓缓冲文件系统是指系统自动地在内存中为每一个正在使用的文件开辟一块“文件缓冲区”,

从内存向磁盘输出数据先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上

如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)

缓冲区的大小根据C编译系统决定

结论:因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题

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

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

相关文章

实战指南:理解 ThreadLocal 原理并用于Java 多线程上下文管理

目录 一、ThreadLocal基本知识回顾分析 (一)ThreadLocal原理 (二)既然ThreadLocalMap的key是弱引用,GC之后key是否为null? (三)ThreadLocal中的内存泄漏问题及JDK处理方法 &…

【StableDiffusion】Embedding 底层原理,Prompt Embedding,嵌入向量

Embedding 是什么? Embedding 是将自然语言词汇,映射为 固定长度 的词向量 的技术 说到这里,需要介绍一下 One-Hot 编码 是什么。 One-Hot 编码 使用了众多 5000 长度的1维矩阵,每个矩阵代表一个词语。 这有坏处&#xff0c…

vscode卡顿问题处理(vue-official插件)

vue官方扩展由volar升级为vue-official,部分人的ide会变得非常卡顿,这是由于vscode本身一些问题导致,如下图作者解释: 解决方式: 通过禁用Hybrid模式,不使用tsserver来接管语言支持,卡顿会缓解…

进击算法工程师深度学习课程

"进击算法工程师深度学习课程"旨在培养学员在深度学习领域的专业技能和实战经验。课程涵盖深度学习基础理论、神经网络架构、模型优化方法等内容,通过项目实践和算法实现,帮助学员掌握深度学习算法原理和应用,提升在算法工程师领域…

如何用多媒体沙盘实现智能交互体验?

随着多媒体技术在内容展示领域的迅猛进步,智能化信息交互方式已然跃升为公众瞩目的焦点,而展厅作为信息传递与产品展示的核心阵地,正面临着提升交互体验、强化信息传递效果的迫切需求。因此,以多媒体沙盘、LED屏幕等创新装置为媒介…

94. 二叉树的中序遍历(Swift实现, 迭代)

题目描述 使用迭代方法解题 class TreeNode {var val: Intvar left: TreeNode?var right: TreeNode?init(_ val: Int) {self.val valself.left nilself.right nil} }func inorderTraversal(_ root: TreeNode?) -> [Int] {var result [Int]() // 用于存储中序遍历…

[深度学习]基于C++和onnxruntime部署yolov10的onnx模型

基于C和ONNX Runtime部署YOLOv10的ONNX模型,可以遵循以下步骤: 准备环境:首先,确保已经下载后指定版本opencv和onnruntime的C库。 模型转换:按照官方源码:https://github.com/THU-MIG/yolov10 安装好yolov…

【OpenVINO™】使用 OpenVINO™ C++ 异步推理接口部署YOLOv8 ——在Intel IGPU 上实现80+FPS视频推理

​ OpenVINO Runtime支持同步或异步模式下的推理。Async API的主要优点是,当设备忙于推理时,应用程序可以并行执行其他任务(例如,填充输入或调度其他请求),而不是等待当前推理首先完成。 当我们使用异步API…

图片查看器

目录 一 原型 二 源码 一 原型 二 源码 namespace 图片查看器 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){//默认显示第一张图片pictureBox1.Image imageList1.Images[0];}private v…

13. 第十三章 案例研究-选择数据结构

13. 案例研究-选择数据结构 到这里尼应该已经学会了Python的核心数据结构, 也见过了一些使用它们的算法. 如果你想要更多地了解算个发可以阅读第21章. 本章配合联系介绍一个案例分析, 帮你思考如何选择数据结构并如何使用它们.13.1 单词频率分析 1. 练习1 编写一个程序, 读入…

《Brave New Words 》9.1 AI 世界中的就业

Part IX: Work and What Comes Next 第九部分:工作及其未来发展 The one who plants trees, knowing that he will never sit in their shade, has at least started to understand the meaning of life. —Rabindranath Tagore 种树的人,虽然知道他永远…

上位机图像处理和嵌入式模块部署(h750 mcu串口命令处理)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面学习103和407的时候,当时学过串口的收发。不过当时使用的主要是阻塞的方式。这一次,我们看下应该怎么利用中断的形式进…

基于flask的网站如何使用https加密通信

文章目录 内容简介网站目录示例生成SSL证书单独使用Flask使用WSGI服务器Nginx反向代理参考资料 内容简介 HTTPS 是一种至关重要的网络安全协议,它通过在 HTTP 协议之上添加 SSL/TLS 层来确保数据传输的安全性和完整性。这有助于防止数据在客户端和服务器之间传输时…

前端实现获取后端返回的文件流并下载

前端实现获取后端返回的文件流并下载 方法一:使用Axios实现文件流下载优点缺点 方法二:使用封装的Request工具实现文件流下载优点缺点 方法三:直接通过URL跳转下载优点缺点 结论 在前端开发中,有时需要从后端获取文件流&#xff0…

Android studio如何导入项目

打开解压好的安装包 找到build.gradle文件 打开查看gradle版本 下载对应的gradle版本Index of /gradle/(镜像网站) 下载all的对应压缩包 配置gradle的环境变量 新建GRADLE_HOME 将GRADLE_HOME加入到path中 将项目在Android studio中打开进行配置 将gr…

前端 CSS 经典:在 Vue3 中使用渐进式图片

1. 什么是渐进式图片 当我们网站会加载很多图片的时候,有些图片尺寸很大,加载就会很慢,会导致页面长时间陷入白屏状态,用户体验很不好。所以可以使用渐进式图片,先给用户展示模糊图,这些图尺寸小&#xff…

嵌入式硬件VS软件,到底哪个更难?

在嵌入式系统开发中,硬件和软件是密不可分的两个方面。但是,究竟是硬件开发更具挑战性,还是软件开发更难以应对呢?本文将就这一问题展开讨论,探究嵌入式硬件和软件在开发过程中的各种挑战与特点。 一、硬件开发&#…

5.7 Python内置函数

文章目录 1. 内置模块Aabs()all()any()ascii() Bbin()bool()bytearra()bytes() Ccallable()chr()classmethod()compile()complex() Ddelattr()dict()dir()divmod() Eenumerate()eval()exec()execfile() Ffile()filter()float()format()frozenset() Ggetattr()globals() Hhasatt…

C++ 23 之 构造函数和析构函数

c23构造函数和析构函数.cpp #include <iostream> #include <string> using namespace std;class Person2{ public:// 构造函数 没有返回值&#xff0c;不能写void;函数名和类名一致&#xff1b;可以设置参数&#xff0c;可以函数重载&#xff1b;系统自动调用&…

人工智能将成为数学家的“副驾驶”

人工智能将成为数学家的“副驾驶” 数学传统上是一门独立的科学。1986年&#xff0c;安德鲁怀尔斯为了证明费马定理&#xff0c;退到书房里呆了7年。由此产生的证明往往很难让同事们理解&#xff0c;有些至今仍有争议。但近年来&#xff0c;越来越多的数学领域被严格地分解为各…