C++新经典05--文件操作

news2025/3/10 10:54:44

文件简介

文件在程序设计中是一个比较重要的概念,这里所说的文件,是指保存在硬盘、U盘等存储介质上的数据,这些存储介质(简称磁盘)上的数据就是以一个个文件的形式体现,每一个文件有一个对应的名字,称为文件名。操作系统也是以文件为单位对数据进行管理,例如想在磁盘上找数据,需要先按照文件名在该磁盘上找到对应文件,然后把文件中的数据读出来。如果要把数据写到磁盘上,也必须先在磁盘上建立一个文件,然后向这个文件中写入数据。

以往程序执行输出的结果信息都是输出到屏幕上,而在程序执行中输入数据是通过键盘用诸如scanf等函数来输入。随着项目越来越庞大,编写的程序功能越来越复杂,不可避免地会将一些数据放到磁盘上长期存储,以后需要这些数据时再从磁盘上把数据读回到计算机内存中,而针对磁盘数据的存取操作,就要用到磁盘文件功能了。

文件可以看成字符序列,例如,“abcdefg”是一个字符串,也是一个字符序列,它是由一个一个的字符顺序排列组成,把这些数据存储到磁盘上,就形成一个文件。
文本文件或者二进制文件是对于人类来说的,而对于计算机,并不区分是什么类型的文件,保存的都是二进制数据,所以,当用文本形式打开文件时,系统会多做一个工作,就是把二进制数据转换成人类能看懂的ASCII码数据。

现在,再说一说对二进制文件的理解。看如下代码:

    short int a;
    int ilen = sizeof(a);//2
    a=10000;
    printf("断点掐在这里观察\n");

把断点设置在printf所在的行并开始调试跟踪,当断点停到printf行时,用前面章节所讲解的办法查看变量a在内存中的内容,如图12.7所示。

文本文件和二进制文件区别详细解释

根据数据组织形式,把文件分为两种:文本文件(ASCII文件)与二进制文件。
· 文本文件:也称为ASCII文件,文件中的每个字节存放一个ASCII码,代表一个字符,这种文件在打开后能够直接看懂其中的内容。
· 二进制文件:把内存中的数据按照其在内存中的存储形式原样输出到磁盘上存放。这种文件中一般会有很多不可见字符,打开后看到的可能是一堆乱码。

文件的打开

文件在进行读或者写之前,必须要先打开,在读或者写结束之后,必须要关闭,否则会造成资源泄漏或读写失败。文件的打开要调用fopen函数。一般形式如下:

在这里插入图片描述
看如下代码:

FILE* fp;
fp = fopen("Al","r");	//打开名字叫"A1"的文件,""表示文件使用方式为只读

这里注意到,fopen函数返回一个指向A1文件的指针,这个指针被赋值给了fp。这样,就可以认为fp指向了A1文件。
FILE结构体:每次用fopen函数打开一个文件,系统都会开辟出一块内存,这块内存大小是sizeof(FILE),这块内存用来存放和文件相关的信息,诸如文件名、文件使用方式、当前文件位置等。

通过调用fopen函数,可以告诉系统三个信息:

1)需要打开的文件名。
2)文件使用方式,如是读还是写,“r”表示读,后面会讲到。
3)让哪个指针变量指向被打开的文件,这里是fp指针变量。

文件使用方式(只包含一部分)如表12.1所示。
在这里插入图片描述
表12.1中的内容不必死记硬背,需要时查阅即可。但这里可以记几个比较常用的,如r、w、a。当然,也有一些规律可循:
(1)有w表示往文件中写入。
(2)有r表示从文件中读出。
(3)有b表示二进制文件。
(4)有a表示追加内容到文件末尾。
(5)有“+”表示既能从文件中读出,又能往文件中写入。

此外,还需要知道的是,每个打开的文件都有一个当前位置指针,其实就是保存在FILE结构里的一个char*型的字符指针(不同版本编译器可能细节不同,但道理都相同)。这个位置指针的用途就是代表当前从文件的哪个位置开始读/写数据,对于读来讲,每读出1字节数据,这个位置指针会自动往后移动1字节,以指向下一字节,这样,下次再读时自然就从下一字节开始。

当用fopen函数打开文件时,有可能打开失败,例如文件不存在时一定会打开失败,此时fopen函数就会返回一个空(NULL)。看如下代码:

在这里插入图片描述

文件的关闭

文件只有在成功用fopen函数打开之后,才存在文件关闭的问题,否则,不存在关闭的问题。在用fopen函数打开文件成功后,一般都会对文件进行读写操作,读写完毕之后,应该关闭这个文件。为什么要关闭这个文件呢?有两个原因:(1)释放这个文件占用的内存资源,如果资源使用后却不释放,那么,当资源耗尽就会导致程序运行崩溃,所以必须养成资源用完后及时释放的好习惯。
(2)往文件中写数据时不会立即往磁盘上写,系统会把数据写到一个叫“缓冲区”的地方,缓冲区满时系统才往磁盘文件上写,写完之后把缓冲区清空继续等待用户往文件中写数据。试想,当把数据往文件中写时,假如缓冲区此时没满,那么在没有关闭文件的情况下退出了程序的运行(或者突然停电导致计算机关机),那么缓冲区中的数据就没来得及写到磁盘文件上,造成数据丢失。关闭文件这个动作会触发系统把缓冲区中的数据立即写到磁盘上,这就避免了缓冲区中的数据丢失问题。

所以,打开的文件在不使用时及时关闭,非常有必要。文件的关闭要调用fclose函数,一般形式如下:
在这里插入图片描述

if(fp != NULL)
	fclose(fp);	//fp就是fopen函数的返回值(文件指针)

文件关闭后,fp就不能再被使用(读/写文件),否则程序会报异常。fclose()函数有返回值,一般0表示关闭成功,非0表示关闭失败,但该返回值用处不大(例如如果文件关闭失败,再关闭一次应该也还会失败),所以一般不用去理会这个返回值。

文件的读写

文件读写有许多相关的函数,这里介绍几个常用的。
(1)fputc函数:用于把一个字符写到磁盘文件。调用形式看如下代码——将字符ch输出到fp所指向的文件中:
在这里插入图片描述
如果fputc执行成功,返回值就是输出字符的ASCII码值;如果执行失败,返回EOF。EOF是EndOfFile(文件末尾)的缩写,是系统提供的一个宏定义,代表-1。如下:
在这里插入图片描述
看看如下范例:

FILE *fp;		//FILE是一个结构,fp是指向结构FILE的指针变量(文件指针)
fp = fopen("FTest.txt","w");	//为写而打开文件
if (fp == NULL)
{
	printf("文件打开失败\n");
}
else
{
	//文件打开成功才走这里
	char reco = fputc('a',fp);
	if (reco == EOF)	//注意fputc失败时,会返回EoF
	{
		
		//写失败时的处理代码
	}
	else
	{
		reco = fputc('d',fp);	//这里并没有判断是否写成功,不建议这样写,不安全
		reco = fputc('e',fp);	//这里依旧没有判断是否写成功
		fclose(fp);	//文件打开成功的情况下,应该及时关闭文件
    }
}

在上面的范例中有几点说明:
· 当执行到fopen这行代码时,文件写入方式指定为w,表示为写而打开一个文本文件FTest.txt,FTest.txt刚开始是不存在的,因此,如果fopen执行成功,则系统会创建该文件,如果该文件存在,则fopen执行成功时该文件中原始的内容会被覆盖。

· 调用fopen函数时可以指定所要打开的文件路径,但范例中并没有指定路径,系统可能会到当前项目所在的目录(通过Visual Studio来运行时)或该可执行程序目录(双击直接运行可执行程序)寻找FTest.txt文件并尝试打开,如果该文件并不存在,系统会在当前项目所在的目录或该可执行程序所在的目录下创建FTest.txt文件。

(2)fgetc函数:用于从指定文件读入一个字符。调用形式看如下代码——从fp所指向的文件中读入一个字符到reco中:

char reco = fgetc(fp);

如果fgetc执行成功,则返回读入的字符;如果执行失败或者整个文件读到末尾,则返回EOF。看看如下范例:

    FILE *fp;    //FILE是一个结构,fp是指向结构FILE的指针变量(文件指针)
    fp = fopen("FTest.txt","r");     //文件刚打开,文件当前位置指针指向开头
    if (fp == NULL)
    {
        printf("文件打开失败");
    }
    else
    {
        //文件打开成功才走这里
        char reco = fgetc(fp);
        //每读一个字符,文件当前位置指针自动向下走一个字符
        while (reco != EOF){    //读入失败或者到文件结束这个条件都成立
            putchar(reco);  //在屏幕上输出一个字符
            reco = fgetc(fp); //再次读一个字符
        }

        fclose(fp);
    }

上面的范例有个弊端,该范例中是用EOF(-1)来判断读入的内容是否到达文件结束。但一旦该文件中真存在一个值为-1的字符(该字符的十六进制是FF,用fgetc读入进来就是-1),那么,用EOF这种判断方式来判断是否读到文件结束,就会出现错误,所以需要换一种范例写法,引入feof函数。

(3)feof函数:用来判断文件是否结束(文件当前位置指针是否指向文件末尾)。调用形式看如下代码:

feof(fp);

如果文件结束,则返回1;如果文件没结束,则返回0。不管使用fopen函数时是以什么样的文件使用方式打开文件(例如用r还是用rb都没关系),feof函数都能够正确地判断文件是否结束。改造一下上面的范例代码,只需要修改范例中的while语句所在行,其他代码行不需要做任何修改。把while语句行修改为如下即可:

while(!feof(fp))	//文件没有结束    

上面的范例中,利用fopen函数打开文件时,如果在“文件使用方式”参数中增加b选项(打开一个二进制文件),代码如下:

 fp = fopen("FTest.txt","rb");

执行程序后会发现,整个程序的运行结果并没有发生什么改变,也就是说,是否增加b选项看起来并没有什么作用。和文件操作相关的函数有不少,但多数都很少用到,不值得花费太多时间去学习,读者有了上面学习的基础,也就有了进一步研究其他文件相关函数的能力,在需要的时候可以自行研究。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

描述性统计:集中趋势和分散

一、说明 在本文中,我们将深入研究描述性统计领域,探索其不同方面,包括统计类型、总体与样本、参数与统计、数据类型以及集中趋势和离散的度量。 让我幽默地向您介绍统计数据。 “统计数据就像比基尼。他们揭示的东西是暗示性的,但…

API开放!将语聚AI智能助手接入到您的自有系统中

概述 语聚AI基于集简云强大的应用软件“连接器”能力,提供了工具延展、知识延展、模型延展和嵌入集成等一系列功能,为用户带来了更加强大和智能的AI新体验。 我们深知,每家企业对于AI应用都有自己独特的需求和应用场景,只有通过开…

接口测试之Postman 安装与使用

Postman 安装 官网下载地址 www.postman.com/downloads Postman 使用 发送get请求 新建请求 填写请求方式:GET 填写请求 URL: ceshiren.com/ httpbin.ceshiren.com/get 填写请求参数: para_key para_value 发送 POST 请求 请求方式&a…

2023年的IC求职究竟有多难?

去年应移知教育要求,写了一篇关于秋招的看法《聊一聊今年的芯片就业市场》,当时提出来的点很简单: ● 处在赛道内的人要正视竞争的难度,提升自身的企业价值分; ● 想要进入赛道的人要放平心态,降低和保留…

C++ string类的模拟实现

模拟实现string类不是为了造一个更好的轮子,而是更加理解string类,从而来掌握string类的使用 string类的接口设计繁多,故而不会全部涵盖到,但是核心的会模拟实现 库中string类是封装在std的命名空间中的,所以在模拟…

ImageKit10 VCL Crack

ImageKit10 VCL Crack ImageKit10 VCL是一个允许您快速轻松地将图像处理功能添加到应用程序中的组件。使用ImageKit10 VCL,您可以编写从TWAIN扫描仪和数码相机检索图像的应用程序;加载和保存图像文件,并将图像从一种格式转换为另一种格式;编辑图像、在图…

MySQL的Json类型字段IN查询分组和优化方法

前言 MySQL从5.7的版本开始支持Json后,我时常在设计表格时习惯性地添加一个Json类型字段,用做列的冗余。毕竟Json的非结构性,存储数据更灵活,比如接口请求记录用于存储请求参数,因为每个接口入参不一致,也…

python的交互式库Qgrid

目录 Qgrid介绍Qgrid使用Qgrid使用过程中遇到的问题解决方案 Qgrid介绍 在Jupyter notebook中直接读取DataFrame数据,只显示为静态表格的形式,没有类似于excel的筛选等交互式功能。Qgrid作为 Jupyter notebook 组件,可以为我们的 DataFrame …

三本书与三场发布会,和鲸社区重新定义编程类书籍从阅读到实践新体验

当 AI 开发者社区配备 AI 基础设施开发平台工具时,它还能做什么? 答案是:过去半年,和鲸社区凭借在气象、医学、社科等垂直领域的长期积累以及多方伙伴的支持,联合举办了三场新书发布会——从 Python 到 R 语言 、从气…

程序员与ChatGPT的交织:探索人工智能和软件开发的新篇章

目录 前言创作者程序员会被替代吗程序员如何更好的使用chatgpt 前言 在技术持续进步的当今世界,程序员与人工智能(AI)之间的关系越来越紧密。特别是对于一些创新性的技术如OpenAI旗下的ChatGPT,这种联系就更为明显。程序员与Chat…

2023/8/16 华为云OCR识别驾驶证、行驶证

目录 一、 注册华为云账号开通识别驾驶证、行驶证服务 二、编写配置文件 2.1、配置秘钥 2.2、 编写配置工具类 三、接口测试 3.1、测试接口 3.2、结果 四、实际工作中遇到的问题 4.1、前端传值问题 4.2、后端获取数据问题 4.3、使用openfeign调用接口报错 4.3、前端显示问题…

python bytes基本用法

目录 1 第一个字符变大写,其余字符变小写 capitalize() 2 生成指定长度内容,然后把指定的bytes放到中间 center() 3 计数 count() 4 解码 decode() 5 是否以指定的内容结尾 endswith() 6 将制表符调整到指定大小 expandtabs() 7 寻找指…

ref拿到组件的实例对象或者原生html标签

在组件中,或者html标签中写ref属性,就是在注册引用 可以通过ref拿到组件的实例对象 也可以通过ref拿到原生的html标签

Linux系统安装及使用HHDBCS

1 安装 1.1 下载HHDBCS 使用浏览器进入官方社区(恒辉产品社区),选择HHDBCS子社区,首页点击下载,进入下载页面; 选择官网下载/云盘下载皆可。 在弹出框中选择如图所示选项,点击下载&#xff…

带着设计思维画版图——第一次和第二次

版图设计目标: 面积小,性能好(少恶化),成本低 设计规则规定了同层与不同层之间的最小距离,因此限制了最小面积 模拟版图设计流程 第一步:设计原理图输入 常用快捷键如下: 介…

YOLO算法封装进入ros系统,识别结果供其他节点订阅

一,前期工作空间搭建 新建工作空间,第一级名称可以换,第二级src最好别换,这是ros系统的固定格式 mkdir -p workspace_yolo/src切换到工作空间 workspace_yolo,进行编译构建项目 cd workspace_yolo/catkin_make输出如下所示: 添加环境变量 cd devel/ 获取到devel文件路径…

模型预测笔记(一):数据清洗分析及可视化、模型搭建、模型训练和预测代码一体化和对应结果展示(可作为baseline)

模型预测 一、导入关键包二、如何载入、分析和保存文件三、修改缺失值3.1 众数3.2 平均值3.3 中位数3.4 0填充 四、修改异常值4.1 删除4.2 替换 五、数据绘图分析5.1 饼状图5.1.1 绘制某一特征的数值情况(二分类) 5.2 柱状图5.2.1 单特征与目标特征之间的…

花生十三 判断推理(三)分析类、推出类

分析类 题型 真假分析 定义:孰真孰假的真假话分析,命题真假无法确定,无法利用推出关系解题 解题思路 矛盾法(三种矛盾):A和非A,“A或B” 与“非A且非B” 技巧:一“找”矛盾&am…

在ARM服务器上一键安装Proxmox VE(以在Oracle Cloud VPS上为例)(甲骨文)

前言 如题,具体用到的说明文档如下 virt.spiritlhl.net 具体流程 首先是按照说明,先得看看自己的服务器符不符合安装 Proxmox VE的条件 https://virt.spiritlhl.net/guide/pve_precheck.html#%E5%90%84%E7%A7%8D%E8%A6%81%E6%B1%82 有提到硬件和软…

C# 读取pcd、ply点云文件数据

最近研究了下用pcl读取点云数据,又做了个C#的dll,方便读取,同样这个dll基于pcl 最新版本1.13.1版本开发。 上次做的需要先得到点云长度,再获取数据。这次这个定义了一个PointCloudXYZ类来存数据。将下面的dll拷贝到可执行目录下&a…