gpt4 book ai didi

c++ - 使用c/c++解析二进制文件

转载 作者:太空宇宙 更新时间:2023-11-04 11:23:37 26 4
gpt4 key购买 nike

我目前正在处理一些二进制文件,数据格式在某些文件中指定。我使用的方式是定义一些相应的结构来从缓冲区中逐一读取数据。例如,如果我知道在文件的开头,有一个数据包头指定了这个数据包中的以下数据类型和数据长度,我将首先解析这个数据包头。

  #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;
}

请注意,在第二种方式(以及使用 header 作为结构)中,您正在进行不必要的复制,我认为您想要的是:

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;
}

除非您出于任何原因故意复制该结构。

关于c++ - 使用c/c++解析二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27436041/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com