c++:位田无法与1位字段正确工作
我已经编写了代码,以保存一些与Cioparams_b_t(请参阅声明)等结构的数据,以归档并加载它们。数字字段(> 1位)成功地从文件加载,但是可能是随机的,带有错误的布尔字段(1位)加载。
保存数据步骤:
//...
std::ofstream file;
file.open(path, std::fstream::out|std::ios::binary|std::ofstream::trunc);
//...
union {
CIOParams_b_t params_b_t;
char raw[6];
} p_data;
p_data.params_b_t.scr_width = params.scr_width;
p_data.params_b_t.scr_hight = params.scr_hight;
p_data.params_b_t.bits = static_cast<int>(params.bits);
p_data.params_b_t.brightness = params.brightness;
p_data.params_b_t.contrast = params.contrast;
p_data.params_b_t.fullscr = getFlag(params.flags, FLAG_FULLSCREEN)?1:0;
p_data.params_b_t.vsync = getFlag(params.flags, FLAG_VSYNC)?1:0;
p_data.params_b_t.mipmap = getFlag(params.flags, FLAG_MIPMAP)?1:0;
p_data.params_b_t.skybox = getFlag(params.flags, FLAG_SKYBOX)?1:0;
file.write(p_data.raw, 6);
//...
加载数据步骤:
//...
std::ifstream file(path);
//...
union {
CIOParams_b_t params_b_t;
char raw[6];
} p_data;
file.read(p_data.raw, 6);
retVal.scr_width = p_data.params_b_t.scr_width;
retVal.scr_hight = p_data.params_b_t.scr_hight;
retVal.bits = static_cast<CIOParams::cbits>(p_data.params_b_t.bits);
retVal.brightness = p_data.params_b_t.brightness;
retVal.contrast = p_data.params_b_t.contrast;
setFlag(&retVal.flags, FLAG_FULLSCREEN, p_data.params_b_t.fullscr==1?true:false);
setFlag(&retVal.flags, FLAG_VSYNC, p_data.params_b_t.vsync==1?true:false);
setFlag(&retVal.flags, FLAG_MIPMAP, p_data.params_b_t.mipmap==1?true:false);
setFlag(&retVal.flags, FLAG_SKYBOX, p_data.params_b_t.skybox==1?true:false);
file.close();
//...
结构声明:
struct CIOParams
{
unsigned short int scr_width;
unsigned short int scr_hight;
unsigned char brightness;
unsigned char contrast;
enum cbits
{
b8 = 0,
b16,
b32,
b64
} bits;
unsigned char flags;
bool hasError = false;
};
struct CIOParams_b_t
{
unsigned scr_width : 10;
unsigned scr_hight : 10;
unsigned bits : 2;
unsigned fullscr : 1;
unsigned vsync : 1;
unsigned brightness : 8;
unsigned contrast : 8;
unsigned mipmap : 1;
unsigned skybox : 1;
unsigned __unused : 6;
};
注意:功能SETFLAG和GETFLAG成功工作。无论如何,他们在单位测试中表现良好。
I have write the code to save some data with structure like CIOParams_b_t (see declaration) to file and load them. Number fields (>1 bits) load from file successfully, however boolean fields (1 bit) load with mistakes, maybe randomly.
save data procedure:
//...
std::ofstream file;
file.open(path, std::fstream::out|std::ios::binary|std::ofstream::trunc);
//...
union {
CIOParams_b_t params_b_t;
char raw[6];
} p_data;
p_data.params_b_t.scr_width = params.scr_width;
p_data.params_b_t.scr_hight = params.scr_hight;
p_data.params_b_t.bits = static_cast<int>(params.bits);
p_data.params_b_t.brightness = params.brightness;
p_data.params_b_t.contrast = params.contrast;
p_data.params_b_t.fullscr = getFlag(params.flags, FLAG_FULLSCREEN)?1:0;
p_data.params_b_t.vsync = getFlag(params.flags, FLAG_VSYNC)?1:0;
p_data.params_b_t.mipmap = getFlag(params.flags, FLAG_MIPMAP)?1:0;
p_data.params_b_t.skybox = getFlag(params.flags, FLAG_SKYBOX)?1:0;
file.write(p_data.raw, 6);
//...
load data procedure:
//...
std::ifstream file(path);
//...
union {
CIOParams_b_t params_b_t;
char raw[6];
} p_data;
file.read(p_data.raw, 6);
retVal.scr_width = p_data.params_b_t.scr_width;
retVal.scr_hight = p_data.params_b_t.scr_hight;
retVal.bits = static_cast<CIOParams::cbits>(p_data.params_b_t.bits);
retVal.brightness = p_data.params_b_t.brightness;
retVal.contrast = p_data.params_b_t.contrast;
setFlag(&retVal.flags, FLAG_FULLSCREEN, p_data.params_b_t.fullscr==1?true:false);
setFlag(&retVal.flags, FLAG_VSYNC, p_data.params_b_t.vsync==1?true:false);
setFlag(&retVal.flags, FLAG_MIPMAP, p_data.params_b_t.mipmap==1?true:false);
setFlag(&retVal.flags, FLAG_SKYBOX, p_data.params_b_t.skybox==1?true:false);
file.close();
//...
structs declaration:
struct CIOParams
{
unsigned short int scr_width;
unsigned short int scr_hight;
unsigned char brightness;
unsigned char contrast;
enum cbits
{
b8 = 0,
b16,
b32,
b64
} bits;
unsigned char flags;
bool hasError = false;
};
struct CIOParams_b_t
{
unsigned scr_width : 10;
unsigned scr_hight : 10;
unsigned bits : 2;
unsigned fullscr : 1;
unsigned vsync : 1;
unsigned brightness : 8;
unsigned contrast : 8;
unsigned mipmap : 1;
unsigned skybox : 1;
unsigned __unused : 6;
};
Notice: functions setFlag and getFlag are working successfully. Anyway, they performed well in unit tests.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于填充字节边界。因此,您认为您的“ cioparams_b_t”类型为6个字节。但这不能保证。在我的环境中,编译器将其填充到8个字节长度:
您可能现在可以尝试使用8个字节,并且可能会起作用。但这不是正确的解决方案。
您需要的就是所谓的序列化。有很多准备免费使用的库免费。但是,对于您的几个数据,您也可以简单地覆盖iSerer
&lt;&lt;
和提取&gt;&gt;
您的课程的操作员。简短示例:
The problem comes with padding over byte boundaries. So, you think that your "CIOParams_b_t" type is 6 bytes long. But that is not guaranteed. In my environment it is padded by the compiler to 8 bytes length:
Then, of course, your function cannot work.
You may have the idea to try with 8 bytes now, and it might work. But this is not the correct solution.
What you need is so called serialization. There are many ready to use libraries available for free. But for your few data, you can also simply overwrite the inserter
<<
and extraction>>
operator for your class.Short example: