使用std :: vector <unsigned char =“”> </unsigned>的内容初始化结构

时间:2014-06-28 20:02:44

标签: c++ c++11 vector struct

这似乎应该简单明了,但谷歌却很少见。

什么是干净,现代(C ++ 11)初始化简单文件头结构的方法,如下所示

typedef struct FooHeader {
    uint8_t    FooCount;
    uint8_t    BarCount;
    uint32_t   BazOffsets[4];
} FooHeader;

包含std::vector<unsigned char>中的数据?创建子向量并将其数据转换为头结构类型或?

是一个好主意

1 个答案:

答案 0 :(得分:3)

为避免遇到打包,对齐和字节序问题,最好在字节级读取数据(在几乎所有现代硬件上,您可以假设8位字节,但打包经常在编译器之间进行更改(甚至只是不同的编译标志之间)和大端和小端计算机仍然很常见。)

这意味着您最好的选择是:

FooHeader load_FooHeader(std::vector<unsigned char> const &dat) {
    static_assert(
        std::numeric_limits<unsigned char>::digits == 8,
        "Assumes 8-bit bytes");

    FooHeader retv;

    retv.FooCount = dat[0];
    retv.BarCount = dat[1];

    //Start at the fifth byte, to allow for padding.
    //If you want to use a packed format, use index = 2;
    std::size_t index{4};
    for (std::size_t i{0}, iend{4}; i < iend; ++i) {
        retv.BarOffsets[i] = 0;
        //Adjust ordering depending on desired endianness.
        //Currently uses little endian.
        for (std::size_t j{0}, jend{4}; j < jend; ++j) {
            retv.BarOffsets[i] |= dat[index + i*4 + (3-j)] << (j*8);
        }
    }

    return retv;
}