vin*_*ind 5 c++ binary struct file
我正在尝试从二进制文件中读取数据并将其放入结构中.前几个字节data.bin是:
03 56 04 FF FF FF ...
Run Code Online (Sandbox Code Playgroud)
我的实施是:
#include <iostream>
#include <fstream>
int main()
{
struct header {
unsigned char type;
unsigned short size;
} fileHeader;
std::ifstream file ("data.bin", std::ios::binary);
file.read ((char*) &fileHeader, sizeof header);
std::cout << "type: " << (int)fileHeader.type;
std::cout << ", size: " << fileHeader.size << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我期待的输出是type: 3, size: 1110,但由于某种原因它是type: 3, size: 65284,所以基本上跳过文件中的第二个字节.这里发生了什么事?
实际上,行为是实现定义的.在你的情况下实际发生的事情可能是,type在结构的成员之后有一个1字节的填充,然后在第二个成员之后size.在看到输出之后,我根据这个论点.
这是你的输入字节:
03 56 04 FF FF FF
Run Code Online (Sandbox Code Playgroud)
第一个字节03转到结构的第一个字节,即type,您将其3视为输出.然后下一个字节56转到第二个字节,这是填充因此被忽略,然后接下来的两个字节04 FF转到结构的下一个两个字节size(大小为2字节).在little-endian机器上,04 FF被解释为0xFF04哪个只是66284你得到的输出.
而且你基本上需要一个紧凑的结构来挤压填充物.使用#pragma包.但是与普通结构相比,这样的结构会很慢.更好的选择是手动填充结构:
char bytes[3];
std::ifstream file ("data.bin", std::ios::binary);
file.read (bytes, sizeof bytes); //read first 3 bytes
//then manually fill the header
fileHeader.type = bytes[0];
fileHeader.size = ((unsigned short) bytes[2] << 8) | bytes[1];
Run Code Online (Sandbox Code Playgroud)
写最后一行的另一种方法是:
fileHeader.size = *reinterpret_cast<unsigned short*>(bytes+1);
Run Code Online (Sandbox Code Playgroud)
但这是实现定义的,因为它取决于机器的endian-ness.在little-endian机器上,它很可能会起作用.
友好的方法是这个(实现定义):
std::ifstream file ("data.bin", std::ios::binary);
file.read (&fileHeader.type, sizeof fileHeader.type);
file.read (reinterpret_cast<char*>(&fileHeader.size), sizeof fileHeader.size);
Run Code Online (Sandbox Code Playgroud)
但同样,最后一行取决于机器的字节序.
| 归档时间: |
|
| 查看次数: |
6064 次 |
| 最近记录: |