读文件到一个结构(C ++) [英] Reading file into a struct (C++)

查看:196
本文介绍了读文件到一个结构(C ++)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从二进制文件中读取数据,并把它变成一个结构。
的data.bin 的前几个字节是:

I'm trying to read data from a binary file and put it into a struct. The first few bytes of data.bin are:

03 56 04 FF FF FF ...

和我的实现是:

#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;

}

我所期待的输出是类型:3,大小:1110 ,但由于某些原因,它的类型:3,大小:65284 ,所以基本上在文件中的第二个字节被跳过。这里发生了什么?

The output I was expecting is type: 3, size: 1110, but for some reason it's type: 3, size: 65284, so basically the second byte in the file is skipped. What's happening here?

推荐答案

其实行为是实现定义。是什么在你的案件实际情况可能是,有1个字节的填充,之后键入结构的成员,那么接下来的第二个成员后大小。我看到后输出基于这一论点。

Actually the behavior is implementation-defined. What actually happens in your case probably is, there is a padding of 1 byte, after type member of the struct, then after that follows the second member size. I based this argument after seeing the output.

下面是你的输入字节:

03 56 04 FF FF FF

第一个字节 03 进入该结构的第一个字节,也就是键入,你看这 3 作为输出。那么下一个字节 56 进入这因此是忽略不计,则填充第二个字节的下两个字节 04 FF 进入哪个是结构尺寸(这是大小 2 字节)的下两个字节。在小端机, 04 FF 是PTED为 0xFF04 间$ P $这是什么,但 66284 ,你得到的输出。

the first byte 03 goes to the first byte of the struct, which is type, and you see this 3 as output. Then next byte 56 goes to the second byte which is the padding hence ignored, then the next two bytes 04 FF goes to the next two bytes of the struct which is size (which is of size 2 bytes). On little-endian machine, 04 FF is interpreted as 0xFF04 which is nothing but 66284 which you get as output.

和你需要基本上是一个紧凑的结构,从而挤压填充。使用的#pragma 包。但是,这样的结构会比正常结构是缓慢的。更好的选择是手工填写的结构为:

And you need basically a compact struct so as to squeeze the padding. Use #pragma pack. But such a struct would be slow compared to the normal struct. A better option is to fill the struct manually as:

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]; 

写的最后一行的另一种方法是这样的:

Another way to write the last line is this:

fileHeader.size = *reinterpret_cast<unsigned short*>(bytes+1); 

但是,这是实现定义的,因为它依赖于机器的字节序。在小端机器,它很可能会工作。

But this is implementation-defined, as it depends on the endian-ness of the machine. On little-endian machine, it most likely would work.

一个友好的方式会是这样(实现定义的):

A friendly approach would be this (implementation-defined):

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

但同样,在最后一行取决于机器的字节序。

But again, the last line depends on the endian-ness of the machine.

这篇关于读文件到一个结构(C ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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