使用 c/c++ 解析二进制文件
Parsing binary files using c/c++
我目前正在处理一些二进制文件,数据格式在某些文件中指定。我使用的方法是定义一些相应的结构,以便从缓冲区中逐个读取数据。例如,如果我知道在文件的开头,有一个数据包标头指定了该数据包中的以下数据类型和数据长度,我将首先解析此数据包标头。
#pragma pack (1)
struct PacketHeader
{
uint16_t PacketSize;
uint16_t PacketType;
};
char *buffer = new char[size];
file.read(buffer, size);
//read in the PacketHeader
PacketHeader ph;
ph = *(PacketHeader *)buffer;
//switch data type
switch(ph.PacketType)
{
//do something
}
到目前为止,一切顺利,但是当我不使用结构方法时会出现问题。例如,我知道在数据类型A
之后缓冲区的某个位置,会有一些关于A
底层组成的信息,比如一个uint32_t
变量,另一个uint32_t
变量。这种变量对的数量在 A
中指定,并且由于该对中只有两个变量,我尝试直接解析它们而没有任何结构,例如,
//get pair_num from previous parsed data
for(int i = 0; i < pair_num; i++)
{
std::cout << (uint32_t)(buffer + 2 * i * sizeof(uint32_t))
<< (uint32_t)(buffer + (2 * i + 1) * sizeof(uint32_t))
<< std::endl;
}
但是,上面的代码不起作用。从文件中解析的两个变量是错误的。所以我回到结构方法,并设法使用以下代码获得正确的结果:
struct B
{
uint32_t v1;
uint32_t v2;
}
B b;
//get pair_num from previous parsed data
for(int i = 0; i < pair_num; i++)
{
b = *(B *)(buffer + i * 8);
std::cout << b.v1
<< b.v2
<< std::endl;
}
我只是想知道这两种方法有什么区别?有人能给我一些见解吗?
不是将char *
转换为uint32_t *
并取消引用它,而是char *
将指针转换为uint32_t
以便在std::cout
上打印地址(或 64 位机器上的一部分地址(,正确的方法应该是这样的:
for(int i = 0; i < pair_num; i++)
{
std::cout << *((uint32_t *)(buffer + 2 * i * sizeof(uint32_t)))
<< *((uint32_t *)(buffer + (2 * i + 1) * sizeof(uint32_t)))
<< std::endl;
}
但更简单的方法是使用适当的指针:
uint32_t *ptr = (uint32_t *) buffer;
for(int i = 0; i < pair_num; i++)
{
std::cout << *(ptr + 2 * i )
<< *(ptr + 2 * i + 1 )
<< std::endl;
}
甚至:
uint32_t *ptr = (uint32_t *) buffer;
for(int i = 0; i < pair_num; i++)
{
std::cout << ptr[2 * i]
<< ptr[2 * i + 1]
<< std::endl;
}
请注意,在第二种方式(以及使用标题作为结构(中,您正在执行不必要的复制,我认为您想要的是:
struct B
{
uint32_t v1;
uint32_t v2;
}
//get pair_num from previous parsed data
for(int i = 0; i < pair_num; i++)
{
B *b = (B *)(buffer + i * 8);
std::cout << b->v1
<< b->v2
<< std::endl;
}
除非您出于某种原因有意复制该结构。
相关文章:
- 正在读取二进制文件(is_open)
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- Android 在编译二进制文件时重建静态库
- 在 C++ 中将双精度变量写入二进制文件
- clang 的 libFuzzer 可以在同一二进制文件中测试超过 1 个 API 吗?
- C++:实际上不是从二进制文件中读取
- 如何从二进制文件中的给定符号中获取调用程序图
- 将内部带有矢量的结构保存/读取到二进制文件中
- 编译多个C++文件.调用二进制文件以运行代码
- 如何使用位字段将数据从二进制文件复制到结构中?
- uint8_t同一二进制文件的不同十进制值
- C++单个生成文件多个二进制文件
- 尝试将数字写入二进制文件时引发异常
- C++中读/写二进制文件
- 如何忽略某些二进制文件的执行?
- 对在不同二进制文件中创建的对象文件的依赖关系
- 我的 SDL2 程序需要哪些二进制文件,以便它在另一台未安装 SDL2 的计算机中工作