c++怎么读取大端序设备的固件bin文件_字节反转与位移操作【详解】

云伟小哥_5409

云伟小哥_5409

2026-03-31

770人浏览

原创

大端序bin文件在小端主机上需手动字节序转换:先用uint8_t数组读取,再通过memcpy构造整数并调用ntohl/ntohs转换;禁止指针强转解引用或直接传地址给ntohl;混合字段须手写位移拼接。

c++怎么读取大端序设备的固件bin文件_字节反转与位移操作【详解】

读取大端序 bin 文件时字节序不匹配导致数据错乱

直接用 fread 读进 uint32_t 变量,结果值完全不对——这是最典型的症状。因为 x86/x64 是小端主机,而固件 bin 是按大端序(network byte order)组织的原始字节流,每个 4 字节字段必须手动翻转。

别依赖编译器或平台自动处理:C++ 标准库不感知 bin 文件的“预期端序”,std::ifstream::read 和 fread 都只是原样搬运字节。

  • 先按字节读(uint8_t 数组),再按需重组整数;或
  • 读入后调用 ntohl/ntohs 转换(仅适用于已知字段长度且对齐的场景);
  • 避免直接把缓冲区指针强转成 uint32_t* 并解引用——这在未对齐或端序不同时会触发未定义行为或错误值。

用 ntohl 处理 32 位字段前必须确保内存对齐和字节填充

ntohl 接收的是 uint32_t 值,不是地址。常见错误是把刚读进的 4 字节缓冲区首地址直接传给它——这会把字节序列解释为小端整数再反转,结果仍是错的。

正确做法是先用 memcpy 构造出一个合法的 uint32_t 值,再转换:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
uint8_t buf[4];
fread(buf, 1, 4, fp);
uint32_t val;
memcpy(&val, buf, 4);  // 安全跨平台赋值
val = ntohl(val);      // 得到正确的大端解析值
  • 不能写 val = *(uint32_t*)buf:未对齐访问在 ARM 等平台会 crash;
  • 如果 bin 文件里字段紧挨着、无 padding,逐字段读比一次性 fread 整块再切片更可控;
  • ntohl 在 Windows 上需 #include <winsock2.h></winsock2.h>,Linux/macOS 用 &lt>arpa/inet.h>;头文件缺失会导致链接失败而非编译报错。

遇到非 4 字节对齐字段(如 16-bit ID + 24-bit payload)只能手写位移拼接

当固件结构含混合宽度字段(比如前 2 字节是大端 uint16_t,后 3 字节是大端编码的 24 位值),ntohs/ntohl 失效,必须拆字节+移位。

例如从 uint8_t raw[3] 解析大端 24 位数:

uint32_t val = (raw[0] 
  • 顺序不能错:raw[0] 是最高位字节,对应 MSB;
  • 用 uint32_t 接收避免符号扩展(若用 int 且 raw[0] > 0x7F,左移可能溢出);
  • 别用 std::bit_cast:C++20 虽支持,但要求源/目标类型 size 相同且 trivial,24 位无原生类型,不适用。

用 std::ifstream 读 bin 时忘记 std::ios::binary 导致 Windows 下换行符被静默替换

在 Windows 上,若以默认文本模式打开 bin 文件,\r\n 会被转成单个 \n,整个文件长度变短、后续所有偏移错位——这不是端序问题,但常被误判为解析逻辑错误。

  • 必须显式指定模式:std::ifstream f("fw.bin", std::ios::binary);
  • std::fstream 同理,不加 binary 标志等于自埋雷;
  • 用 f.gcount() 检查每次 read() 实际读取字节数,若小于预期,优先排查是否开了文本模式。
实际处理固件 bin 时,端序只是表象;真正复杂的是字段边界是否隐含 padding、是否有可变长段、校验和位置是否固定——这些不会报错,但会让解析结果乍看合理、实则运行时崩溃。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

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

2023.08.02

5939

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

2925

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

3728

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2605

10

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

339

31

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

2025.09.03

1652

14

css中的padding属性作用
css中的padding属性作用

在CSS中,padding属性用于设置元素的内边距。想了解更多padding的相关内容,可以阅读本专题下面的文章。

2023.12.07

2692

3

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3159

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2718

6

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习