2015-05-19 94 views
4

FREAD(CUR,2,1,FIN)Ç - 二读,FREAD被颠倒顺序

我相信,我会觉得自己很蠢,当我得到一个答案,但发生了什么? curl是一个指向code_cur的指针,short(2字节),fin是一个打开二进制读取的流。

如果我的文件是00101000 01000000

我到底得的是

code_cur = 01000000 00101000 

这是为什么?我还没有举办任何比赛,因为这个问题真的可以归结为(至少对我而言)意想不到的行为。

而且,如果这是正常的,我如何获得所需的效果?

P.S.

我应该补充一点,为了'查看'字节,我正在打印它们的整数值。

printf("%d\n",code_cur) 

我试了几次,它似乎可靠。

+9

恭喜!你已经发现[endianness](https://en.wikipedia.org/wiki/Endianness)。 –

+3

你可能会发现[** this **](http://en.wikipedia.org/wiki/Endianness)有趣。 – WhozCraig

+0

@WhozCraig Okok我发现了热水。那么,是否有标准的说法呢? 我现在唯一能想到的就是'切片'我的短片并重新组合它,但我会认为某件事情是这样的,因为布线是内置的。 –

回答

3

正如其他人指出,您需要了解更多关于endianness

你不知道它,但你的文件是(幸运的)在网络字节顺序(这是Big Endian)。您的机器是小端,所以需要更正。需要或不需要,总是建议这种修正,因为这可以保证你的程序在任何地方都能运行。

做somethig与此类似:

{ 
    uint16_t tmp; 

    if (1 == fread(&tmp, 2, 1, fin)) { /* Check fread finished well */ 
     code_cur = ntohs(tmp); 
    } else { 
     /* Treat error however you see fit */ 
     perror("Error reading file"); 
     exit(EXIT_FAILURE); // requires #include <stdlib.h> 
    } 
} 

ntohs()将你的价值从文件顺序转换到你的机器的命令,不管它是什么,或大或小端。

+1

注意:'ntohs'不是ISO C,而是POSIX,可能不适用于某个系统。此外,还应包括'arpa/inet.h'。 – edmz

1

这就是为什么htonl和htons(和朋友)存在。它们不是C标准库的一部分,但它们几乎可用于任何联网的平台。

“htonl”表示“主机到网络,长”; “htons”意思是“主机到网络,简称”。在这种情况下,“long”意味着32位,“short”意味着16位(即使平台声明“long”是64位)。基本上,每当你从“网络”(或者你的案例中,你正在阅读的流)中读取某些内容时,就会通过“ntoh *”传递它。当你写出来的时候,你通过它“hton *”

你可以以任何你想要的方式排列这些函数名,除了那些愚蠢的东西(不,没有ntons,也没有stonl)