【问题标题】:Processing binary data containing different length处理包含不同长度的二进制数据
【发布时间】:2020-11-13 06:16:27
【问题描述】:


所以我有一些我读取、处理并需要“拆分”为不同变量的二进制数据,如下所示:

int *buffer;
buffer = malloc(size); 
fread(buffer,size,1,file);
buffer = foo(buffer);

结果在我的调试器中看起来像这样:

01326A18 5F4E8E19 5F0A0000

我希望第一个字节 (01) 是 int a
以下4个字节是第一个时间戳b(应该是5F186A32
以下4个字节是第二个时间戳c(应该是5F198E4E
0A 应该是 int d

我的问题是我可以将 1 放入 a 中,(*buffer) & 0xff;,
但我无法正确读取第一个时间戳,因为它是从第二个字节到第 5 个字节,并且与 int 声明不一致缓冲区。 如果我打印 *(buffer +1) 它会给我第二个 int 并打印“198E4E5F” 如果我能够从数据中的每个位置定位 n 个字节,那就更好了。

提前谢谢。

【问题讨论】:

  • 我希望buffer = foo(buffer);只是一个例子,因为它破坏了malloc分配的内存。
  • 这篇文章真的需要展示你的努力,inC。即提供minimal reproducible example,然后在该上下文中您的问题描述可能有意义。
  • @PaulOgilvie buffer = foo(buffer); 不需要破坏内存。例如,分配可能是为了反映在foo() 内完成的realloc()
  • 为什么不使用内部有正确变量的结构并立即开始读取整个结构?像 fread(some_struct, sizeof(struct), 1, file)。
  • 后面4个字节是第一个时间戳b(应该是5F186A32这到底是什么意思? b 在哪里定义?你从看第一个字节01,然后说接下来的4个字节要转换为时间戳b5F186A32 来自哪里?

标签: c buffer binaryfiles


【解决方案1】:

这样的东西可以在大多数 little-endian 平台上运行。以同样的方式阅读。

struct {
  uint8_t a;
  uint32_t timeStamp1;
  uint32_t timeStamp2;
  uint8_t d;
} buffer __attribute__((packed));
assert(sizeof buffer == 10);  /* check packing */

【讨论】:

  • __attribute__ 不是标准 C。当然,正如您所提到的,即使在具有该扩展名的实现上,这种方法也依赖于实现的 uint32_t 的字节序以匹配在文件。
【解决方案2】:

如果您将缓冲区类型设置为char*,这将使其指向块的 1 个字节。然后如果尝试获取buffer+2,它将返回缓冲区的第二个字节,不像int指针将返回缓冲区的第8个字节。不要忘记在malloc 调用中更新您的size,因为在这种情况下,您的内存是1 字节块。 this link 也可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 2012-04-20
    • 2020-03-30
    • 2010-12-24
    • 2021-09-19
    相关资源
    最近更新 更多