| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 用C语言随机读写二进制文件 -> 正文阅读 |
|
[C++知识库]用C语言随机读写二进制文件 |
本节主要讨论如何使用C语言随机读写二进制文件。
文件既可以顺序读写,也可以随机读写。所谓顺序读写,可以简单理解为从头读/写到尾,数据项是一个接着一个进行读取/写入的;而随机读写则允许我们随时改变文件的当前读写位置,如果在非文件尾的位置写入内容,则相应位置的原始数据会被覆盖。 二进制文件可以视为字节流,程序为每一个被打开的二进制文件维护了一个读写位置标记,该标记为一个整数,表示当前读写位置相对于文件起始处的偏移量,以字节为单位。随着文件读写操作的进行,该读写位置会自动后移,其偏移量等于读写操作的字节数。 表20-6 文件随机访问函数(C语言)
表20-6列出了C语言中用于二进制文件随机访问的常用函数,以这些函数为工具,我们可以在文件中随意移动读写位置,方便地读写二进制文件。 C语言程序BinaryPriceList展示了一个灵活的二进制商品价格表存储结构,该结构以不重复的固定的商品编号为基础进行工作。
上述代码的执行结果为:
上述程序执行完成后,我们得到一个二进制文件commodity.dat,其尺寸为96字节。为了便于描述上述程序的随机读写过程及工作原理,我们画出了commodity.dat的内部结构,请见图20-7。请读者注意,图20-7只是一个示意图,其并不能“精细”表达commodity.dat的内部结构。 🚩第14 ~ 27行:locateCommodity()函数用于在已打开的二进制文件f中查找编号为iNo的商品价格信息。如果查找成功,函数将f的读写位置移至对应的商品价格信息的起始处并返回true,否则返回false。 🚩第15行:rewind(f)将文件f的读写位置移至文件头,即地址0处。 🚩第17 ~ 26行:通过while“死”循环对文件进行顺序查找。 🚩第18 ~ 19行:从文件f读取商品编号至整数t,如果fread()函数的返回值不是1,说明已抵达文件尾,查找失败,返回false。 🚩第20 ~ 23行:如果第18行读到的商品编号t等于iNo,说明找到了指定记录,使用fseek()函数将读写位置后退4个字节至该商品价格信息的起始处,然后返回true。此处的SEEK_CUR表示参考位置为当前位置,负的sizeof(int)表示回退4个字节。 🚩第25行:如果第18行读到的商品编号t不等于iNo,说明匹配不成功,使用fseek()函数将当前读写位置前移28个字节至下一条商品价格信息的起始处,然后继续循环。 表20-7列出了locateCommodity(f,3)的执行过程,请读者结合图20-7进行分析。 表20-7 locateCommodity(f,3)的执行过程
🚩第29 ~ 37行:saveCommodity()函数用于将c所指向的商品价格对象存入文件f,如果对应编号的商品价格记录已存在,则覆盖更新原有信息。 🚩第30 ~ 31行:使用locateCommodity()函数在文件f中定位指定商品编号的记录。如果locateCommodity()返回false,表示未找到,则将读写位置移至文件尾,准备在文件尾追加新记录。此处的SEEK_END表示参考位置为文件尾,0表示相对于文件尾偏移0字节。 🚩第33 ~ 36行:向文件中依次写入商品编号、名称、价格以及库存数量。当读写位置位于文件尾时,这4行代码的执行结果相当于往文件尾附加了一条新记录。当读写位置位于locateCommodity()函数定位的原有记录的起始处,这4行代码的执行结果相当于覆盖更新了原有记录。 🚩第39 ~ 48行:loadCommodity()函数从文件中查找并读取指定编号的商品价格信息至c指向的结构体。如果指定的编号不存在,返回false,否则返回true。 🚩第40 ~ 41行:使用locateCommodity()定位指定编号的记录,如果没找到,返回false表示读取失败。 🚩第43 ~ 46行:如果指定编号的记录在文件中存在,locateCommodity()函数执行后,文件的读写位置正好位于该记录的起始处。依次读入编号、名称、价格和库存数量。 🚩第47行:返回true表示读取成功。 🚩第55 ~ 59行:以二进制读写模式打开文件commodity.dat备用。程序第一次运行时,commodity.dat文件可能不存在,以wb+模式打开,该模式确保当文件不存在时,自动新建一个文件。程序第N次运行时,commodity.dat文件已存在,以rb+模式打开,该模式确保文件的原有内容不会被截断。 函数access()用于判断文件fname是否具体指定的访问权限,其原型如下。当文件具有指定的权限时,返回0,否则返回-1。
参数mode可以为F_OK、X_OK、W_OK和R_OK等值,依次表示文件是否存在、是否可执行、是否可写、是否可读。 🚩第61 ~ 62行:存入编号为1的商品价格信息。在程序第1次运行时,第62行在文件中新增记录;在第N次运行时,第62行在文件中覆盖更新记录。 🚩第64行:打印输出文件的当前读写位置。由于刚刚在第62行写入1号商品信息完毕,该读写位置的理论值应为32,因为如前所述,一行记录空间占用正好是32字节。 🚩第66 ~ 69行:存储3号及5号商品价格信息。 🚩第70 ~ 71行:修改3号商品的名称,再次将其写入文件。第71行执行前3号商品记录肯定已存在于文件中,因此第71行事实上覆盖更新了原有记录。执行结果的第7行证实,3号商品的名称被正确修改为Pork。 🚩第73 ~ 81行:逐一读取并打印编号1至5的商品价格信息。执行结果的第6行和第8行证实,由于2号商品和4号商品不存在,第77行的loadCommodity()返回了false,第78行将对应的商品名称打印为“NA”,意为不可用(not available)。 🚩第83行:关闭文件f。 为了帮助更多的年轻朋友们学好编程,作者在B站上开了两门免费的网课,一门零基础讲Python,一门零基础C和C++一起学,拿走不谢! 如果你觉得纸质书看起来更顺手,目前Python有两本,C和C++在出版过程中。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 5:59:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |