如何在C ++中从文件中读取大端整数?

时间:2013-11-03 08:29:45

标签: c++

说我有一个二进制文件;它包含正二进制数,但以大端编写为32位整数

如何阅读此文件?我现在有这个。

int main() {
    FILE * fp;
    char buffer[4];
    int num = 0;
    fp=fopen("file.bin","rb");
    while ( fread(&buffer, 1, 4,fp) != 0) {

        // I think buffer should be 32 bit integer I read,
        // how can I let num equal to 32 bit big endian integer?
    }
    return 0;
}

3 个答案:

答案 0 :(得分:7)

将缓冲区声明为:

unsigned char buffer[4];

你可以用它来转换字数:

int num = (int)buffer[0] | (int)buffer[1]<<8 | (int)buffer[2]<<16 | (int)buffer[3]<<24;

<强>顺便说一句

当然这适用于小端的x86架构 - 否则您的平台endianess可能与您的文件的endianess匹配,因此不需要转换。通过这种方式,您可以直接读入您的int而无需进行修改。

答案 1 :(得分:4)

您需要先了解您的结尾:

How can I find Endian-ness of my PC programmatically using C?

然后你需要采取相应的行动。如果您与文件相同,则可以按原样读取该值,如果您处于不同的endianess,则需要重新排序字节:

union Num 
{
    char buffer[4];
    int num;
} num ;

void swapChars(char* pChar1, char* pChar2)
{
    char temp = *pChar1;
    *pChar1 = *pChar2;
    *pChar2 = temp;
}

int swapOrder(Num num)
{
    swapChar( &num.buffer[0], &num.buffer[3]);
    swapChar( &num.buffer[1], &num.buffer[2]);

    return num.num; 
}

while ( fread(&num.buffer, 1, 4,fp) != 0)
{
    int convertedNum;
    if (1 == amIBigEndian) 
    {
        convertedNum = num.num
    } 
    else
    {
        convertedNum = swapOrder(num);
    }
    // Do what ever you want with convertedNum here...
}

答案 2 :(得分:3)

这是特定于操作系统和处理器体系结构。

您可能也可以使用htonl(3)ntohl等常规...

但你确实应该以明确定义的格式serialized

在当前的机器上(I / O非常慢,CPU速度很快)我赞成使用文本序列化格式,如JSONYAML,....但你也可以使用二进制序列化(和库),如BSONXDRASN.1s11n库....

如果可能,请改进生产者代码(编写您的file.bin文件)和相应的消费者代码。

二进制数据本质上是脆弱的,因为它是系统和体系结构特定的。至少,非常好地记录其格式,并且最好提供一些工具来将其转换为文本格式。

C ++有几个JSON库,比如jsoncpprapidjson,C代表jansson等等......