我正在尝试将位字段结构写入文件然后读取它。
例如:
typedef struct{
ushort
a:4,
b:4,
c:4,
d:4;
} teststruct;
我尝试像这样写作和阅读
QDataStream &operator <<(QDataStream &st, const teststruct &a)
{
st <<a.a << a.b << a.c << a.d;
return st;
}
QDataStream &operator >>(QDataStream &st, teststruct &a)
{
st >>a.a >> a.b >> a.c >> a.d;
return st;
}
teststruct str1, str2;
str1.a = 1;
str1.b = 0;
str1.c = 1;
str1.d = 0;
QFile f("testfile");
f.open(QFile::WriteOnly);
QDataStream st(&f);
st << str1;
f.close();
f.open(QFile::ReadOnly);
QDataStream st(&f);
st >> str2;
f.close();
但在QDataStream::operator>>
我收到了错误
错误:无法绑定位域&#39; a.teststruct :: a&#39;到&#39; quint16&amp; {又简称 unsigned int&amp;}&#39;
我可以使用>>
运算符做什么,或者可能有其他方法将数据读取到我的结构中?
答案 0 :(得分:0)
在您的示例中,您应该注意到保存到文件的数据可能不正确。例如,具有以下结构:
struct BitStruct
{
uint8_t b1:4;
uint8_t b2:4;
};
并且操作符写为:
QDataStream &operator <<(QDataStream &st, const BitStruct &a)
{
st <<a.b1 << a.b2;
return st;
}
将样本数据BitStruct bits{0x1, 0x2};
写入文件时,将写入2个字节。文件的二进制内容为0x01 0x02
,这可能不是您想要达到的目的。
这是因为调用st << a.b1
会导致b1
字段转换为QDataStream
处理的类型之一,在这种情况下很可能是quint8
QDataStream::operator<<
(你可以在docs中阅读更多内容。)
要解决此问题,您可以将st.writeRawData(reinterpret_cast<const char*>(&a), sizeof(BitStruct));
实施修改为:
QDataStream::operator>>
另一方面,要将数据读取到此类结构,您应该在st.readRawData(reinterpret_cast<char*>(&a), sizeof(BitStruct));
实现中执行类似的更新:
cipher text
这将允许按照预期的紧凑方式编写结构并相应地读取特定的位字段。
通过这种方式,您可以在单一方法中编写/读取整个结构,并且不必担心结构的进一步增长(其他字段)并更新两个运算符实现。
答案 1 :(得分:0)
我认为你拥有你的位域结构的原因是它的大小是ushort
(真的uint16_t
),并且通过值传递它是便宜的并且它需要尽可能小的空间。这是一个正当的理由,所以让我们继续吧。
请注意,结构的内存布局与磁盘布局没有任何关系!磁盘布局取决于您使用QDataStream
及其运算符的方式。显示它时的磁盘布局浪费了75%的空间 - 每个值占用16位,但它只需要4:
(uint16_t a) (uint16_t b) (uint16_t c) (uint16_t d)
修复它的关键是使用中间值作为结构和数据流之间的接口。
因此:
QDataStream &operator <<(QDataStream &st, const teststruct &a)
{
uint8_t v0 = (a.d << 4) | a.c;
uint8_t v1 = (a.b << 4) | a.a;
st << v0 << v1;
return st;
}
QDataStream &operator >>(QDataStream &st, teststruct &a)
{
uint8_t v0, v1;
st >> v0 >> v1;
a.a = v1;
a.b = v1>>4;
a.c = v0;
a.d = v0>>4;
return st;
}
磁盘布局现在不浪费空间,如下(使用假型):
[(uint4_t d) (uint4_t c)] [(uint4_t b) (uint4_t a)]