2015-11-03 76 views
2

整數我想要做的:讀了一系列的4個字節例如00000000 00000011 00000001 00000011(這是一個隨機示例)從二進制文件,並表示它作爲在我的程序的整數。做這個的最好方式是什麼?字節從二進制文件

編輯解決方案我忽略了規範的PNG文件格式here的這部分,希望這是任何人發現的問題非常有用。

我正在與PNG圖像格式進行實驗時遇到了問題中提取的4字節數。我已經成功地打開和打印文件的二進制表示,所以我知道我一起工作的數據沒有損壞或者不正確。

我回顧了像Reading 16-bit integers from binary file c++和32位等價物的問題,但我無法辨別他們是否正在讀取二進制文件中的整數,例如00000000 72 00000000或以整數讀取字節,這是我的目標。

作爲示例,第一個塊的前四個字節是00000000 00000000 00000000 0000110113

繼像上面的問題的例子中,這應該== 13:

int test; 
img.read((char*) &test, sizeof(test)); 

但它輸出218103808

我也嘗試使用聯合與一個字符陣列和整數的方法數據成員,並得到了218103808

也是相同的輸出,我的系統上sizeof(int)等於4

最後,只是要確定它是不是一個畸形的PNG(這不是我比較肯定)我用GIMP導入它,然後將其導出爲一個新的文件,所以我的系統上本地創建的。

編輯

正如我所說,seekg(8)後,接下來的四個字節是00000000 00000000 00000000 00001101但是當我決定使用測試read功能

bitset<32> num; 
img.read((char*) &num, sizeof(int)); 

它輸出00001101 00000000 00000000 00000000 我只是通過這個困惑部分,在這裏。就好像字節在這裏被顛倒一樣。而這個字符串的字節相當於218103808

任何有識之士將不勝感激

+0

有關如何開始的一般概念,您可能需要查看一下我的舊答案。 http://stackoverflow.com/a/5762648/179910 –

+0

謝謝,這是相當有幫助的。我對於爲什麼得到我編輯中提到的值「218103808」有點遺憾。我在你的頭文件驗證功能中看到它。我知道它表示的是13的長度,但它爲什麼會損壞到另一個數字?再次感謝 –

+0

我想你對小端符號感到困惑。 https://en.wikipedia.org/wiki/Endianness的第一段應該讓你走上正軌。 –

回答

3

注意,218103808是0x0D000000十六進制。你可能想了解Endianess

這意味着你正在閱讀的數據是大端格式,而你的平臺使用小尾數。

基本上你需要扭轉的4個字節,(你可能想使用無符號整數),讓您得到0x0000000D,(13十進制),你可以這樣做:

#define BSWAPUINT(x) ((((x) & 0x000000ff) << 24) |\ 
         (((x) & 0x0000ff00) << 8) |\ 
         (((x) & 0x00ff0000) >> 8) |\ 
         (((x) & 0xff000000) >> 24)) 
unsigned int test; 
img.read((char*) &test, sizeof(test)); 
test = BSWAPUINT(test); 

將上面的代碼只有在代碼運行在小端平臺上時纔有效。

要讓你的代碼是獨立於你的平臺是否是大或小端,你可以自己組裝字節整數,因爲你知道的數據格式爲大端,你可以這樣做:

unsigned char buf[4]; 
unsigned int test; 
img.read((char*) &test, sizeof(test)); 
test = (unsigned int)buf[0] << 24; 
test |= buf[1] << 16; 
test |= buf[2] << 8; 
test |= buf[3]; 

或者,在UNIX系統上,你可以#include <arpa/inet.h>和使用ntohl()

test = ntohl(test); 

(與數據處理以這種方式,你也更好地利用類型(如uint32_t)的不是int/unsigned int類型的,從stdint.h

+0

這當然是這種情況。當我研究文件格式時,我無法相信我忽視了PNG的排序。萬分感謝 –