【C语言标准库函数】标准输入输出函数详解[4]:二进制文件读写函数

目录

一、fread() 函数

1.1. 函数简介

1.2. fread 使用场景

1.3. 注意事项

1.4. 示例

二、fwrite() 函数

2.1. 函数简介

2.2. fwrite 使用场景

2.3. 注意事项

2.4. 示例

三、总结


在 C 语言中,二进制文件读写函数允许以二进制形式对文件进行读写操作,这种方式可以高效地处理非文本数据,如图片、音频、视频等。

一、fread() 函数

1.1. 函数简介

函数原型

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 功能:从文件流中读取数据。
  • 参数
    • ptr:指向存储读取数据的缓冲区的指针。
    • size:每个数据项的大小(以字节为单位)。
    • nmemb:要读取的数据项的数量。
    • stream:文件指针。
  • 返回值:实际读取的数据项的数量,可能会小于请求的数量。

1.2. fread 使用场景

fread 函数是 C 语言中用于从文件中读取数据到缓冲区的一个非常强大的工具。它特别适用于处理二进制文件,但也同样适用于文本文件。fread 的使用场景包括但不限于。

  • 读取二进制文件:如读取图像文件、音频文件或其他任何类型的二进制数据。fread 能够按字节精确控制数据的读取,非常适合处理这类文件。
  • 读取大型数据文件:当需要处理的数据量非常大时,fread 可以通过控制读取的块大小(size 和 count 参数)来优化内存使用和读取速度。
  • 结构体的序列化与反序列化:在需要将结构体数据保存到文件,或从文件中恢复结构体数据时,fread 可以用来读取或写入结构体的字节表示。

1.3. 注意事项

  • 文件打开模式:在使用 fread 之前,需要确保文件以正确的模式(如 "rb" 用于二进制读取)打开。
  • 缓冲区分配:需要为 fread 提供一个足够大的缓冲区来存放读取的数据。如果缓冲区太小,可能会导致数据丢失或读取失败。
  • 返回值检查:fread 的返回值是实际读取的数据项个数,可能与请求读取的项数不同(如到达文件末尾或发生错误)。因此,需要检查返回值以确保读取成功。
  • 文件关闭:完成文件读取后,应使用 fclose 函数关闭文件,以释放资源并避免潜在的文件损坏。
  • 错误处理:应准备好处理 fread 可能遇到的错误,如文件不存在、读取权限不足等。

1.4. 示例

以下是一个使用 fread 读取二进制文件的简单示例:

#include <stdio.h>  
#include <stdlib.h>  int main() {  FILE *fp;  int data[10]; // 假设我们要读取10个整数  size_t numRead;  // 以二进制读取模式打开文件  fp = fopen("data.bin", "rb");  if (fp == NULL) {  printf("Failed to open file\n");  return 1;  }  // 读取数据  numRead = fread(data, sizeof(int), 10, fp);  // 检查是否成功读取了所有数据  if (numRead < 10) {  if (feof(fp)) {  printf("End of file reached before reading 10 integers\n");  } else if (ferror(fp)) {  perror("Error reading file");  }  }  // 关闭文件  fclose(fp);  // 假设这里对读取到的数据进行处理...  return 0;  
}

尝试从名为 "data.bin" 的二进制文件中读取 10 个整数,并将它们存储在 data 数组中。检查 fread 的返回值以确保所有数据都被成功读取,并在读取完毕后关闭文件。如果读取过程中遇到错误或到达文件末尾,我们会相应地打印错误信息或提示。

二、fwrite() 函数

2.1. 函数简介

函数原型

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 功能:向文件流中写入数据。
  • 参数
    • ptr:指向要写入数据的缓冲区的指针。
    • size:每个数据项的大小(以字节为单位)。
    • nmemb:要写入的数据项的数量。
    • stream:文件指针。
  • 返回值:实际写入的数据项的数量,可能会小于请求的数量。

2.2. fwrite 使用场景

fwrite 函数是一个广泛使用的文件写入函数,尤其在C/C++等编程语言中。它的主要使用场景包括:

  • 写入二进制文件:fwrite 非常适合将二进制数据写入文件,比如图片、音频文件或任何需要以字节为单位存储的数据。
  • 写入结构体数据:当需要将结构体数据持久化到文件中时,fwrite 可以将结构体的内存表示直接写入文件,方便后续的读取和恢复。
  • 写入文本文件:尽管通常推荐使用更适合文本处理的函数(如fprintf)写入文本文件,但fwrite 同样可以用于写入文本数据,尤其是在处理非ASCII字符或需要精确控制字节写入时。
  • 日志记录:在某些情况下,fwrite 可以用于将程序的日志信息写入文件,尽管这通常不是其首选用途,因为它不提供格式化输出的功能。
  • 配置文件写入:在需要将配置信息保存到文件中时,fwrite 可以将配置数据以二进制或文本形式写入,取决于数据的性质和文件的使用方式。
  • 网络数据保存:在处理网络数据时,fwrite 可以用于将接收到的网络数据保存到本地文件中,以便后续分析或处理。

2.3. 注意事项

  • 文件打开模式:在使用 fwrite 之前,需要确保文件以正确的模式(如 "wb" 用于二进制写入)打开。
  • 数据类型匹配:写入的数据类型应与文件打开模式相匹配。例如,以二进制模式打开的文件应写入字节数据。
  • 缓冲区大小:fwrite 允许一次性写入多个数据项,但需要注意缓冲区的大小,以避免溢出或不必要的内存使用。
  • 返回值检查:fwrite 的返回值表示实际写入的数据项个数,可能与请求写入的数据项个数不同。应检查返回值以确保数据正确写入。
  • 文件关闭:完成文件写入后,应使用 fclose 函数关闭文件,以释放资源并避免潜在的文件损坏。
  • 错误处理:应准备好处理 fwrite 可能遇到的错误,如磁盘空间不足、写入权限不足等。

2.4. 示例

以下是一个使用 fwrite 写入二进制数据的简单C语言示例:

#include <stdio.h>  int main() {  FILE *fp;  char *data = "Hello, World!"; // 注意:这里以字符串为例,实际二进制数据应使用字节数组  size_t written;  // 以二进制写入模式打开文件  fp = fopen("output.bin", "wb");  if (fp == NULL) {  perror("Failed to open file");  return 1;  }  // 注意:如果写入的是字符串,并且文件是二进制模式,可能需要转换为字节数组  // 这里为了简化示例,直接写入字符串(在实际二进制文件中可能不适用)  // 正确的做法是将字符串转换为字节数组,或者确保文件以文本模式打开  written = fwrite(data, sizeof(char), strlen(data), fp);  // 检查是否成功写入所有数据  if (written < strlen(data)) {  perror("Error writing to file");  }  // 关闭文件  fclose(fp);  return 0;  
}  // 注意:上面的示例为了简化,直接将字符串写入了二进制文件。  
// 在实际应用中,如果文件是二进制文件,应该使用字节数组来存储要写入的数据。  
// 例如,可以将字符串转换为字节数组,或者使用其他二进制数据作为fwrite的参数。

上面的示例中直接写入了字符串,在处理二进制文件时通常不是最佳做法。在处理二进制文件时,应使用字节数组来存储和写入数据。此外,如果文件是以文本模式打开的(如 "wt"),则不应使用 fwrite 写入二进制数据,而应使用如 fprintf 之类的函数。

三、总结

二进制文件读写在C语言中主要通过fwritefread函数实现。fwrite用于将数据以二进制形式写入文件,而fread则用于从文件中读取二进制数据。这两个函数都需指定数据指针、数据项大小、数据项数量以及文件指针。在使用时,要确保文件以二进制模式打开,并注意检查返回值以处理可能的错误。二进制文件读写提供了对文件内容的低级访问,适用于需要直接处理原始数据的场景。

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

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

相关文章

食品饮料生产瓶颈?富唯智能协作机器人来 “破壁”

在食品和饮料行业的发展进程中&#xff0c;诸多生产瓶颈如重复性劳动负担、复杂环境作业难题、季节性产能波动等&#xff0c;长期制约着企业的高效运营与进一步发展。如今&#xff0c;富唯智能协作机器人的出现&#xff0c;为这些难题提供了完美的解决方案&#xff0c;正逐步改…

[创业之路-289]:《产品开发管理-方法.流程.工具 》-15- 需求管理 - 第1步:原始需求收集

概述&#xff1a; 需求收集是需求管理的第一步&#xff0c;也是产品开发、项目管理或软件设计中的关键步骤。原始需求收集主要是指从各种来源获取关于产品或服务的初步需求和期望。 以下是对需求管理中的原始需求收集的详细分析&#xff1a; 1、原始需求收集的目的 原始需求…

81页精品PPT | 华为流程与信息化实践与架构规划分享

华为流程与信息化实践与架构规划分享主要围绕华为在业务流程与信息化建设方面的经验、企业架构规划方法以及企业数字化转型路径展开。华为通过持续的业务变革和信息化建设&#xff0c;从本土企业逐步发展为国际化、全球化企业&#xff0c;其管理体系以持续创新和世界级管理体系…

DeepSeek 实践总结

目录 1、与AI对话-万能公式 chatbox 谷歌插件方式 命令行方式 2、ChatPPT+DeepSeek形成PPT 1、与AI对话-万能公式 *明确身份+任务+细节描述+输出格式* 这样的方式能更加准确的帮助你快速获得接近你想法的内容。 身份:你是谁?(网络负责人/记者/老师。。。)任务:要解决什…

51c自动驾驶~合集49

我自己的原文哦~ https://blog.51cto.com/whaosoft/13164876 #Ultra-AV 轨迹预测新基准&#xff01;清华开源&#xff1a;统一自动驾驶纵向轨迹数据集 自动驾驶车辆在交通运输领域展现出巨大潜力&#xff0c;而理解其纵向驾驶行为是实现安全高效自动驾驶的关键。现有的开…

【AI学习】LLM的发展方向

个人的思考&#xff0c;请大家批评。 这一轮AI浪潮&#xff0c;叙事的主要逻辑就是scaling law&#xff0c;模型越大&#xff0c;性能越好&#xff0c;投入越大&#xff0c;性能越好&#xff0c;回报越高&#xff0c;等等。当然&#xff0c;首先要有一个能够scaling的模型架构…

C语言学习笔记:子函数的调用实现各个位的累加和

在C语言程序学习之初&#xff0c;我们都会学习如何打印 hello world&#xff0c;在学习时我们知道了int main&#xff08;&#xff09;是主函数&#xff0c;程序从main函数开始执行&#xff0c;这是流程控制的一部分内容。在主函数中我们想要实现一些功能&#xff0c;比如求各个…

白话文实战Nacos(保姆级教程)

前言 上一篇博客 我们创建好了微服务项目,本篇博客来体验一下Nacos作为注册中心和配置中心的功能。 注册中心 如果我们启动了一个Nacos注册中心,那么微服务比如订单服务,启动后就可以连上注册中心把自己注册上去,这过程就是服务注册。每个微服务,比如商品服务都应该注册…

2025.2.9 每日学习记录2:技术报告写了一半+一点点读后感

0.近期主任务线 1.完成小论文准备 目标是3月份完成实验点1的全部实验和论文。 2.准备教资笔试 打算留个十多天左右&#xff0c;一次性备考笔试的三个科目 1.实习申请技术准备&#xff1a;微调、Agent、RAG 1.今日完成任务 1.电子斗蛐蛐&#xff08;文本书写领域&am…

【Git】ssh如何配置gitlab+github

当我们工作项目在gitlab上&#xff0c;又希望同时能更新自己个人的github项目时&#xff0c;可能因为隐私问题&#xff0c;不能使用同一′密钥。就需要在本地电脑上分别配置两次ssh。 1、分别创建ssh key 在用户主目录下&#xff0c;查询是否存在“.ssh”文件&#xff1a; 如…

【设计模式】【行为型模式】职责链模式(Chain of Responsibility)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f4eb; 欢迎V&#xff1a; flzjcsg2&#xff0c;我们共同讨论Java深渊的奥秘 &#x1f…

Spring Boot牵手Redisson:分布式锁实战秘籍

一、引言 在当今的分布式系统架构中,随着业务规模的不断扩大和系统复杂度的日益增加,如何确保多个服务节点之间的数据一致性和操作的原子性成为了一个至关重要的问题。在单机环境下,我们可以轻松地使用线程锁或进程锁来控制对共享资源的访问,但在分布式系统中,由于各个服务…

apache-poi导出excel数据

excel导出 自动设置宽度&#xff0c;设置标题框&#xff0c;设置数据边框。 excel导出 添加依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency>…

畅游Diffusion数字人(16):由音乐驱动跳舞视频生成

畅游Diffusion数字人(0):专栏文章导航 前言:从Pose到跳舞视频生成的工作非常多,但是还没有直接从音乐驱动生成的工作。最近字节跳动提出了MuseDance,无需复杂的动作引导输入(如姿势或深度序列),从而使不同专业水平的用户都能轻松进行灵活且富有创意的视频生成。 目录 贡…

Kokoro 开源文本转语音引擎上线!多语言支持,无需联网,浏览器内极速运行

Kokoro 是一款轻量级的开源文本转语音(TTS)引擎,凭借其高效能和轻量化设计,迅速在技术社区中引起关注。本文将详细介绍 Kokoro 的主要特点,并提供在浏览器和 Python 环境中的代码示例,帮助您快速上手。 1. Kokoro:可在浏览器中运行的 TTS 引擎 1.1 简介 Kokoro 是一个…

人工智能学习(七)之神经网络

目录 一、引言 二、经典神经网络回顾 &#xff08;一&#xff09;结构与计算过程 &#xff08;二&#xff09;局限性 三、循环神经网络&#xff08;RNN&#xff09;原理 &#xff08;一&#xff09;基本结构 &#xff08;二&#xff09;计算过程 &#xff08;三&#xf…

在Java中操作Redis

4.在Java中操作Redis 4.1 Redis的Java客户端 前面我们讲解了Redis的常用命令&#xff0c;这些命令是我们操作Redis的基础&#xff0c;那么我们在java程序中应该如何操作Redis呢&#xff1f;这就需要使用Redis的Java客户端&#xff0c;就如同我们使用JDBC操作MySQL数据库一样。…

大语言模型需要的可观测性数据的关联方式

可观测性数据的关联方式及其优缺点 随着现代分布式架构和微服务的普及&#xff0c;可观测性&#xff08;Observability&#xff09;已经成为确保系统健康、排查故障、优化性能的重要组成部分。有效的可观测性数据关联方式不仅能够帮助我们实时监控系统的运行状态&#xff0c;还…

棱光PDF工具箱:一站式解决你的各种需要

今天为大家介绍一款非常实用且完全免费的PDF工具箱——棱光PDF工具箱。它功能强大&#xff0c;操作简单&#xff0c;能够满足你对PDF文件的各种处理需求&#xff0c;包括添加水印、去除水印、批量转换格式等&#xff0c;绝对值得推荐&#xff01; 棱光PDF工具箱 棱光PDF工具箱…

Docker安装Redis

一、保证Docker提起来了 systemctl status docker想这没有启动要先启动一下 systemctl status docke二、拉取Redis&#xff08;默认拉最新版&#xff09; sudo docker pull redis检查一下拉成功没有 docker images三、创建相关目录 mkdir -p /home/redis/{conf,data}四、…