2014-12-24 148 views
-5

我有一個二進制文件,我需要閱讀32位整數。但是當我使用ifstream.read()(C++)和fread()(C)時,他們給了我一個完全錯誤的答案。我認爲它是向後讀取整數值。例如,如果我讀取位串\0\0\0\r(轉換爲字符),那麼當我得到值13時,我得到值218,103,808。這些值轉換爲二進制值:如何從二進制文件讀取整數與C + +和C

0000 1101 0000 0000 0000 0000 0000 0000(218,103,808)

0000 0000 0000 0000 0000 0000 0000 1101(13)

和轉換爲二進制位串應該是:

0000 0000 0000 0000 0000 0000 0000 1101(\0\0\0\r

,因爲前三個字節是空字符,最後一個字節的ASCII值是13

所以首先,糾正我,如果我說的是錯誤的,第二,爲什麼它給出值爲218,103,808而不是13?第三,我怎樣才能得到13的理想結果?

這裏是一些其他有用的信息:代碼

行,我用的是閱讀file.read((char*)&i, 4);其中i是一個unsigned int和文件是ifstream;和fread(&i, 4, 1, file);其中i又是一個無符號整數,文件是FILE*

如果我只讀最後一個字節\r那麼我確實得到了正確的值,但我需要能夠讀取任何int,而不僅僅是那些可以放入1個字節數據的int。

如果我可以得到答案只有一個,C或C++,這將是偉大的,但我希望爲C和C++的答案。

在此先感謝!

+0

聽起來像一個Endianess問題。你可能想看看'ntohl()'''htonl()'函數。 – alk

+0

看起來你已經暴露了你的計算機的字節序 – Daniel

+0

如果'i'是一個無符號整數,你爲什麼要將它轉換爲'char *'?其他與本主題相關的其他鏈接問題是否有幫助?特別是*如何從C++中的文件中讀取小端字節*,*從C *中的文件中讀取二進制整數,*從文件中讀取二進制數並將其保存爲整數*,*從文件中讀取二進制*,*從C *中的文件中讀取二進制整數,以及*如何使用fread讀取二進制文件中的整數* *。 –

回答

0

該文件已按小端字節順序寫入。您的機器使用大端字節順序。或相反亦然。顯而易見的解決方案是在讀取和寫入時反轉字節順序。這裏有很多問題可以涵蓋。

更深層次,您可能會考慮是否應該使用機器字節順序來寫入文件(如果確實如此)。一種常見的方法是使用網絡字節順序(總是大端)編寫文件,然後在讀取數據時轉換爲主機字節順序(機器字節順序)。

然後再次或許該文件是按網絡字節順序寫入的,並且您的程序剛剛錯過了轉換爲主機字節順序所需的步驟。

這個程序

#include <stdio.h> 
#include <stdint.h> 

uint32_t reversed(uint32_t val) 
{ 
    return ((val>>24)&0xff) | 
      ((val<<8)&0xff0000) | 
      ((val>>8)&0xff00) | 
      ((val<<24)&0xff000000); 
} 

int main(void) 
{ 
    uint32_t val = 13; 
    printf("%d\n", val); 
    printf("%d\n", reversed(val)); 
    return 0; 
} 

有這樣的輸出:

 
13 
218103808 

這些是你的問題的兩個值。我相信這讓你確信你有一個簡單的排序顛倒。