【问题标题】:C++ How to read Bytes as Integer endianness independent?C ++如何将字节读取为独立的整数字节顺序?
【发布时间】:2016-06-15 17:52:09
【问题描述】:

我想将我的文件的一些字节作为整数值读取。例如,文件包含值 0x000003BB,等于 955。

我可以这样读取数据:

ifstream input ("C:/Desktop/myFile", ios::binary);
uint8_t buffer[4] = {0};
input.read((char*)buffer, sizeof(buffer));

但是如何将缓冲区数组转换为相应的 int 值 955?如果可能的话,以独立于字节序的方式,因为这个文件和其他一些大字节序的文件,但我的系统是小字节序的。谢谢:)

【问题讨论】:

    标签: c++ io int byte endianness


    【解决方案1】:

    如果你的操作系统支持POSIX或者是windows,那么你可以使用ntohl:

    int data;
    input >> data;
    data = ntohl(data);
    

    【讨论】:

    • 在 Windows 上,它需要链接到 Ws2_32.lib
    【解决方案2】:

    我不确定这是不是最好的解决方案,但它确实有效。

    uint8_t buffer[4] = {0};
    input.read((char*)buffer, sizeof(buffer));
    unsigned int result = buffer[0];
    result = (result << 8) | buffer[1];
    result = (result << 8) | buffer[2];
    result = (result << 8) | buffer[3];
    

    【讨论】:

    • 它没有考虑字节序。如果我打印出数据变量,我得到的值是“3137536000”,它等于“0xBB030000”,但我需要得到“0x000003BB”
    • @Opa114 实际上,这段代码确实考虑字节序,因为它可以在任何字节序的机器上工作。这只是一个错误,这会转换 little 字节序,而不是您想要的大字节序。将缓冲区索引从 0 更改为 3,就可以了。
    【解决方案3】:

    不用uint8_t的数组,直接读入4字节整数即可:

    uint32_t data;
    input.read((char*)&data, sizeof(data));
    

    编辑:

    此代码适用于我的 VC++ 编译器:

    #include<stdint.h>
    #include<intrin.h>
    #include<iostream>
    
    int main()
    {
        uint32_t data;
        data = 0xBB030000;
        data = _byteswap_ulong(data);
    
        std::cout << data;
    }
    

    如果您使用的是 GCC,则需要将 _byteswap_ulong 替换为 __builtin_bswap32。如果您需要独立代码,则需要编写自己的代码(可能在这些编译器内在函数之上)。

    【讨论】:

    • 这行得通,但它没有考虑字节序。如果我打印出 data-var,我会得到值 3137536000,它等于“0xBB030000”,但我需要得到 0x000003BB
    • 仍然落入同样的陷阱,阿杰。 OP 不知道文件是大还是小,他们希望通用代码来处理这两种情况。任何未指定字节序的文件协议都是有缺陷的,应该返回实验室重新设计,但是....
    • 数字不保持字节序!
    • 没错。问题归结为“如何安全地确定文件的字节序?”没有更多信息,你不能。该文件必须具有某种标签或值,可以测试其有效性,并且仅在一个字节序中有效。 OP 没有指定任何这些。
    猜你喜欢
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多