提问人:Richard Williams 提问时间:11/4/2022 更新时间:11/4/2022 访问量:323
从二进制文件(大端序)读取到具有多种数据类型的结构体中
Reading from a binary file (big endian) into a struct with multiple data types
问:
我有一个二进制格式,它有一堆重复的 32 位整数(按大端顺序排列),类似于这样:
[int a, int b, int c][int a, int b, int c][...]
我简化了很多。struct/binary 文件中实际上有更多的值(但二进制文件都是整数)。我最终想要做的是从文件中读取并创建如下所示的结构:
struct Foo
{
int a;
float b;
float c;
};
其中浮点数只是 b 和 c 的整数值乘以 0.1。
我最初的想法是我应该重载结构?std::ifstream operator>>
Foo
我读了这篇关于从 big-endian 流中读取 int 的文章。
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
但我不确定如何将其扩展到更大的结构?
我想到的另一种方法是只使用 ,然后遍历结构中的单词并交换字节,但这只会让我得到一个 ints 的结构。infile.read()
我觉得我需要编写一个以 4 个字节读取的流重载。交换它们,如果结构值是浮点数,则将 int 乘以 0.10(不确定我是否需要先转换它)。
我可以用 c 语言轻松完成所有这些工作,但只是想学习 idomatic c++ 的做事方式。
答:
我只会使用 fread()。然后使用 htonl() 调用循环。由于一切都是 32 位的,如果你想是可移植的,我会使用 int32_t 而不是 int,因为 int 的大小取决于实现。由于数据在技术上是 int32 数据,因此我使结构如下所示:
union wrapper {
int32_t i;
float f;
};
然后使你的结构:
struct Foo
{
int a;
wrapper b;
wrapper c;
};
在C++中,我还会做一个静态断言,即 sizeof(union wrapper) == sizeof(int32_t)。
在读取数据之前,我还会调用 stat() 来获取文件的大小并确认它是 struct Foo 的倍数。
评论
operator>>
std::ifstream::read
fread
for
for (size_t index = 0; index < sizeof(val); index++)
val
for
val