将原始结构内容(字节)写入C中的文件.混淆写入的实际大小

d11*_*wtq 7 c struct sizeof fwrite

基本问题,但我希望这个结构占用13个字节的空间(1表示char,12表示3个无符号整数).相反,sizeof(ESPR_REL_HEADER)给我16个字节.

typedef struct {
  unsigned char version;
  unsigned int  root_node_num;
  unsigned int  node_size;
  unsigned int  node_count;
} ESPR_REL_HEADER;
Run Code Online (Sandbox Code Playgroud)

我要做的是用一些值初始化这个结构并将它包含的数据(原始字节)写入文件的开头,这样当我打开这个文件后我才能重构这个结构并获得一些元数据有关文件其余部分包含内容的数据.

我正在初始化结构并将其写入文件,如下所示:

int esprime_write_btree_header(FILE * fp, unsigned int node_size) {
  ESPR_REL_HEADER header = {
    .version       = 1,
    .root_node_num = 0,
    .node_size     = node_size,
    .node_count    = 1
  };

  return fwrite(&header, sizeof(ESPR_REL_HEADER), 1, fp);
}
Run Code Online (Sandbox Code Playgroud)

node_size我实验时目前在哪里4.

在我向其编写结构后,该文件包含以下数据:

-bash$  hexdump test.dat
0000000 01 bf f9 8b 00 00 00 00 04 00 00 00 01 00 00 00
0000010
Run Code Online (Sandbox Code Playgroud)

我希望它实际上包含:

-bash$  hexdump test.dat
0000000 01 00 00 00 00 04 00 00 00 01 00 00 00
0000010
Run Code Online (Sandbox Code Playgroud)

请原谅新生.我正在努力学习:)如何有效地将我的struct的数据组件写入文件?

Pot*_*ter 6

微处理器不是为从任意地址获取数据而设计的.诸如4字节ints之类的对象应仅存储在可被4整除的地址中.此要求称为对齐.

C使编译器可以自由地在struct成员之间插入填充字节以对齐它们.填充量只是不同平台之间的一个变量,另一个主要变量是字节序.这就是为什么如果您希望程序在多台计算机上运行,​​您不应该简单地将结构"转储"到磁盘上.

最佳实践是显式编写每个成员,并用于htonl在二进制输出之前将字节序修复为big-endian.回读时,用于memcpy移动原始字节,不要使用

char *buffer_ptr;
...
++ buffer_ptr;
struct.member = * (int *) buffer_ptr; /* potential alignment error */
Run Code Online (Sandbox Code Playgroud)

而是做

memcpy( buffer_ptr, (char *) & struct.member, sizeof struct.member );
struct.member = ntohl( struct.member ); /* if member is 4 bytes */
Run Code Online (Sandbox Code Playgroud)