0

0

C++ 怎么把结构体写入文件 C++ fwrite直接操作内存块教程【IO】

尼克

尼克

发布时间:2026-02-03 14:59:03

|

873人浏览过

|

来源于php中文网

原创

结构体能用 fwrite 直接写入文件仅当满足标准布局且不含指针、引用、虚函数或非平凡构造/析构函数;含 std::string 等动态成员会导致写入垃圾地址,须用 static_assert 检查并改用固定长度数组与紧凑对齐。

c++ 怎么把结构体写入文件 c++ fwrite直接操作内存块教程【io】

fwrite 写结构体前必须确认内存布局是否可直接序列化

结构体能用 fwrite 直接写入文件,仅当它满足“标准布局(standard layout)”且不含指针、引用、虚函数、非平凡构造/析构函数。否则写进去的是垃圾地址或未定义行为。

常见踩坑:含 std::stringstd::vectorstd::shared_ptr 的结构体——这些成员在内存中只存控制块指针,fwrite 会把指针值写进文件,读取时完全无法还原。

  • 检查方式:static_assert(std::is_standard_layout_v, "not standard layout");
  • 禁用 std::string,改用固定长度 C 风格数组(如 char name[32];
  • 避免访问控制符混用(比如 public 成员后跟 private 成员),这可能破坏标准布局

fwrite 写结构体的正确调用姿势和参数含义

fwrite 本质是按字节拷贝内存块,不是“写结构体”,所以传参必须严格对应:地址、单个元素大小、元素个数、文件流。

错误写法:fwrite(&s, sizeof(s), 1, fp) 看似对,但若结构体有填充字节(padding),且你后续用不同编译器/平台读取,可能因填充位置不一致导致错位。

立即学习C++免费学习笔记(深入)”;

  • 务必用 sizeof(MyStruct) 而非 sizeof(s)(后者虽等价,但易掩盖类型变更风险)
  • 写多个时:fwrite(arr, sizeof(MyStruct), count, fp),不要写成 fwrite(arr, count * sizeof(MyStruct), 1, fp) —— 后者在出错时无法区分是写入0个还是1个大块
  • 写完必须检查返回值:if (fwrite(...) != 1) { /* handle error */ }fwrite 返回成功写入的“项数”,不是字节数

跨平台/跨编译器读写结构体时必须处理字节序和对齐

即使结构体是 POD 类型,fwrite/fread 在 x86 和 ARM、MSVC 和 GCC 下仍可能因默认对齐策略不同而读错字段——尤其含 short/int/long 混排时。

Dora
Dora

创建令人惊叹的3D动画网站,无需编写一行代码。

下载

例如:MSVC 默认 8 字节对齐,GCC 可能按成员自然对齐;一个含 char a; int b; 的结构体,在不同编译器下 sizeof 可能是 8 或 5(加 #pragma pack(1) 后)。

  • 统一强制紧凑对齐:#pragma pack(push, 1) 包围结构体定义,再 #pragma pack(pop)
  • 整数字段需手动转主机序→网络序(如用 htons/htonl),否则在小端机写、大端机读会全乱
  • 文件头建议写 magic number + version + size,用于校验兼容性,避免静默读错

替代方案:什么时候不该用 fwrite 直接写结构体

只要结构体里有任何动态资源(哪怕只是 char* 指向堆内存)、或需要版本演进、或要被 Python/Java 等语言读取,fwrite 就不再是合理选择。

此时应切换为文本格式(JSON/INI)或二进制协议(Protocol Buffers、Cap’n Proto),哪怕多几行代码,也比后期调试字节错位强十倍。

  • fwrite 适合:嵌入式日志缓存、同进程复用的临时快照、性能敏感且生命周期封闭的场景
  • 不适合:持久化用户数据、网络传输、长期存档、含业务逻辑的配置
  • 若坚持用二进制,至少封装一层:MyStruct::serialize(FILE*)MyStruct::deserialize(FILE*),把字节序/填充/校验逻辑收口

实际操作中最容易被忽略的,是填充字节与字节序的组合效应——同一段代码在本地测试全对,一上 ARM 服务器就解析失败,而且错误表现常是某个 int 字段值极小或极大,很难联想到是大小端问题。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

425

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

538

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

313

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

78

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

543

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

790

2023.08.22

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

268

2023.10.18

全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

4

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号