2015-05-19 70 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)