写入原始结构的内容(字节)的文件在C困惑写的实际大小 [英] Write raw struct contents (bytes) to a file in C. Confused about actual size written

查看:154
本文介绍了写入原始结构的内容(字节)的文件在C困惑写的实际大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本的问题,但我希望这个结构中占据13个字节的空间(1焦炭,12为3无符号整数)。相反,的sizeof(ESPR_REL_HEADER)给我16个字节。

Basic question, but I expected this struct to occupy 13 bytes of space (1 for the char, 12 for the 3 unsigned ints). Instead, sizeof(ESPR_REL_HEADER) gives me 16 bytes.

typedef struct {
  unsigned char version;
  unsigned int  root_node_num;
  unsigned int  node_size;
  unsigned int  node_count;
} ESPR_REL_HEADER;

我试图做的是一些值初始化这个结构,并写入一个文件的开始它包含的数据(原始字节),这样,当我打开这个文件我后,我可以重建这种结构和获得有关什么文件的其余部分包含一些元数据

What I'm trying to do is initialize this struct with some values and write the data it contains (the raw bytes) to the start of a file, so that when I open this file I later I can reconstruct this struct and gain some meta data about what the rest of the file contains.

我在初始化结构,并将其写入文件是这样的:

I'm initializing the struct and writing it to the file like this:

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);
}

其中, node_size 目前是4,而我的实验。

Where node_size is currently 4 while I experiment.

该文件包含以下数据我写的结构来后:

The file contains the following data after I write the struct to it:

-bash$  hexdump test.dat
0000000 01 bf f9 8b 00 00 00 00 04 00 00 00 01 00 00 00
0000010

我希望它实际上包含:

I expect it to actually contain:

-bash$  hexdump test.dat
0000000 01 00 00 00 00 04 00 00 00 01 00 00 00
0000010

对不起的newbiness。我想学习:)我如何高效地编写只是我结构的数据组件到一个文件?

Excuse the newbiness. I am trying to learn :) How do I efficiently write just the data components of my struct to a file?

推荐答案

微处理器不是设计来从任意地址的数据。对象,如4个字节的 INT 取值只能存放在四整除的地址。这一要求被称为对准

Microprocessors are not designed to fetch data from arbitrary addresses. Objects such as 4-byte ints should only be stored at addresses divisible by four. This requirement is called alignment.

C给出编译器自由地插入填充字节结构成员对齐它们之间。填充量是不同的平台,另一个主要的变量被字节顺序之间只有一个变量。这就是为什么你不应该简单地倾销的结构到磁盘,如果你想程序在多台机器上运行。

C gives the compiler freedom to insert padding bytes between struct members to align them. The amount of padding is just one variable between different platforms, another major variable being endianness. This is why you should not simply "dump" structures to disk if you want the program to run on more than one machine.

最好的做法是明确地写出每一个成员,并使用 htonl 二进制输出之前解决字节顺序为大端。当回读,使用的memcpy 移动原始字节,不要使用

The best practice is to write each member explicitly, and to use htonl to fix endianness to big-endian before binary output. When reading back, use memcpy to move raw bytes, do not use

char *buffer_ptr;
...
++ buffer_ptr;
struct.member = * (int *) buffer_ptr; /* potential alignment error */

而是做

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

这篇关于写入原始结构的内容(字节)的文件在C困惑写的实际大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆