我需要将结构中包含的数据写入二进制文件。

假设给定的结构

struct data {
unsigned char sig;
int reserved;
}

我希望能够简单地将此结构的内容输出到文件中。

我试图用这个

fstream out("C:\\somepath", ios::out | ios::app | ios::binary);
data writedata;
writedata.sig = 'BM';
writedata.reserved = NULL;
out.write((char*)&writedata, sizeof(writedata));
out.close();

我期望输出为(使用32位编译器(十六进制为4字节,以十六进制表示)):

42 4D 00 00 00 00

但这不是印刷的内容。

有人可以解释为什么它不起作用以及修复它所需的步骤吗?

谢谢。

===============>>#1 票数:2 已采纳

首先, 'BM'是两个字节,不能装入单个unsigned char'BM'可能被编译器视为多字节文字,这可能不是您想要的)。

然后,编译器可以自由地在结构内部添加填充以使其与正确的单词边界对齐; 在x86上,正确的成员资格保证更好的读取性能;在其他体系结构上,如果对齐错误,则会出现硬件异常。

例如,在您的情况下,在32位x86上,结构的二进制布局将是sig一个字节,填充的三个字节,然后是reserved int (为了获得最佳访问速度,它将在4字节边界对齐) 。

没有避免填充的标准方法。 您必须诉诸于编译器特有的技巧。 在VC ++上,您必须使用#pragma pack ,g ++和clang也受支持,尽管它们的“本机”方式是使用__attribute__(packed)

顺便说一句,如果您必须向文件中写入“便携式”文件格式(例如您尝试编写的DIB),请始终使用固定大小的整数类型(来自stdint.h ),并准备好处理字节序问题。计划移植到其他架构。

===============>>#2 票数:0

我看到的编译器错误/警告:

  1. 失踪; data定义的末尾。
  2. 评估'BM'是错误的。 它必须是单个字符。
  3. NULL分配给data.reserved 您应该做到:

     data.reserved = 0; 

如果要最小化磁盘上文件占用的空间,请分别写入结构的每个字段。

out.write((char*)&writedata.sig, sizeof(writedata.sig));
out.write((char*)&writedata.reserved, sizeof(writedata.reserved));

我注意到的另一件事是,您正在使用ios::app标志打开文件。 它追加到现有文件。 你是这个意思吗? 如果不是,则可以删除该标志。

  ask by Jason Mills translate from so

未解决问题?本站智能推荐: