用c++编写一个二进制结构
write a struct in binary in c++
我需要将结构中包含的数据写入二进制文件。
假设给定的结构
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位编译器(所以int是4个字节)):
42 4D 00 00 00 00
但这不是印刷出来的。
有人能解释一下为什么这不起作用,以及修复它所需的步骤吗?
谢谢。
首先,'BM'
是两个字节,不能放在一个unsigned char
中(编译器可能会将'BM'
视为多字节文字,这可能不是您想要的)。
然后,编译器可以自由地在结构内部添加填充,以使其与正确的单词边界对齐;在x86上,正确的成员对齐可以保证更好的读取性能,而在其他体系结构上,如果对齐错误,则会出现硬件异常。
例如,在您的情况下,在32位x86上,结构的二进制布局将是一个字节的sig
、三个字节的填充,然后是reserved
int
(将在4字节边界上对齐以获得最佳访问速度)。
没有标准的方法可以避免填充;你必须采用编译器特有的技巧。在VC++上,您必须使用#pragma pack
,g++和clang也支持它,尽管它们的"原生"方式是使用__attribute__(packed)
。
顺便说一句,如果您必须将"可移植"文件格式写入文件(如您试图写入的DIB),请始终使用固定大小的整数类型(来自stdint.h
),并且如果您计划移植到其他体系结构,请准备好处理端序问题。
我看到的编译器错误/警告:
- 在
data
的定义末尾缺少;
- 分配
'BM'
是错误的。它需要是单个字符 -
将
NULL
分配给data.reserved
。你应该做到:data.reserved = 0;
如果要最大限度地减少文件在磁盘上占用的空间,请分别写入结构的每个字段。
out.write((char*)&writedata.sig, sizeof(writedata.sig));
out.write((char*)&writedata.reserved, sizeof(writedata.reserved));
我注意到的另一件事是,您打开的文件带有标志ios::app
。它附加到现有文件中。你是这个意思吗?如果没有,您可以删除该标志。
- 将XSD文件嵌入一个(二进制文件)中
- 从一个二进制文件中读取信息,并写入另一个二进制文件
- 将 tesseract 编译/捆绑为一个二进制文件
- 如何将所有依赖项和共享库编译为一个二进制文件
- 如何用C++在windows上制作一个二进制兼容的动态库
- C 打开一个二进制文件
- 在 Google 的C++测试框架中为多个单元测试创建一个二进制文件
- 我可以为一个包含向量的C++结构写一个二进制吗
- 我试图证明一个给定的树是一个二进制搜索树.我将输入一个二叉树,我只想让函数返回true
- 构建一个二进制字符串c++
- 铬嵌入框架(C++)和另一个二进制之间的IPC
- 从一个二进制树复制到另一个
- c++将一个文件读入一个结构并写入一个二进制文件
- 找到与另一个二进制模式匹配的所有 2 位值,然后对它们求和
- 用C++实现一个二进制信号量类
- 将4位写入到一个二进制文件中,其中包含ofstream
- 创建一个二进制文件,向其中添加信息,并从中读取所有记录(电话簿)
- C++用另一个二进制文件编辑二进制文件
- 找出(在c++中)二进制数是否是另一个二进制数的前缀
- 用c++中的映像创建一个二进制文件