加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在没有填充位的情况下在C中输出二进制文件

发布时间:2020-12-16 09:57:49 所属栏目:百科 来源:网络整理
导读:我想将结构数据输出到二进制文件,但每个变量的信息之间没有任何填充位.例如: struct s { int i1; short s1; char c1;};struct s example[2]; 如果我使用fwrite( example,sizeof(struct s),2,file),二进制文件仍然具有填充位,例如s1和c1之间,以及c1到i1(第二
我想将结构数据输出到二进制文件,但每个变量的信息之间没有任何填充位.例如:

struct s {
    int i1;
    short s1;
    char c1;
};
struct s example[2];

如果我使用fwrite(& example,sizeof(struct s),2,file),二进制文件仍然具有填充位,例如s1和c1之间,以及c1到i1(第二结构)之间的填充位.

从输出文件中删除这些填充位的好方法是什么?

谢谢!任何帮助表示赞赏

解决方法

我建议单独手动读取/写入结构的成员.使用编译器指令进行打包可能会导致未对齐数据访问的低效率和可移植性问题.如果你必须处理字节序,那么稍后当你的读操作分解为字段成员而不是整个结构时,很容易支持.

另一件事,这与未来的维护类型问题有关,就是你不希望你的序列化代码或人们迄今为止保存的文件中断,如果你稍微改变一下结构(添加新元素甚至改变顺序)作为高速缓存行优化,例如).因此,与使用直接将结构的内存内容直接转储到文件中提供更多喘息空间的代码相比,您可能会遇到更少的痛苦,而且通常最终值得单独序列化您的成员.

如果要概括模式并减少所编写的样板量,可以执行以下操作作为启动和构建的基本示例:

struct Fields
{
     int num;
     void* ptrs[max_fields];
     int sizes[max_fields];
};

void field_push(struct Fields* fields,void* ptr,int size)
{
    assert(fields->num < max_fields);
    fields->ptrs[fields->num] = ptr;
    fields->sizes[fields->num] = size;
    ++fields->num;
}

struct Fields s_fields(struct s* inst)
{
    struct Fields new_fields;
    new_fields.num = 0;

    field_push(&new_fields,&inst->i1,sizeof inst->i1);
    field_push(&new_fields,&inst->s1,sizeof inst->s1);
    field_push(&new_fields,&inst->c1,sizeof inst->c1);

    return new_fields;
}

现在,您可以将此Fields结构与通用函数一起使用来读取和写入任何结构的成员,如下所示:

void write_fields(FILE* file,struct Fields* fields)
{
    int j=0;
    for (; j < fields->num; ++j)
         fwrite(fields->ptrs[j],fields->sizes[j],1,file);
}

这通常比一些功能性的for_each_field接受回调的方法更容易使用.

现在你要创建一些新的结构S时要担心的是,定义一个函数来从一个实例输出struct Fields,然后启用你编写的所有那些使用struct Fields的通用函数来使用这个新的S自动输入.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读