2014-02-21 60 views
2

我一直在努力刷新我的C最近,並正在編寫一個程序來手動解析通過PNG文件。Char陣列的整數轉換

我看到的PNG文件在十六進制編輯器,發現字節流,看起來像

00 00 00 0D 

十六進制格式。

此字符串理應代表我感興趣的長度。

我用getc(file)的PNG文件的字節拉。

我創建字符數組作爲

char example[8]; 

存儲從getc檢索到的字符。現在

,我已填充example

printf("%#x, %#x, %#x, %#x", example[0].... 

打印它顯示0, 0, 0, 0xd這正是我想要的。

然而,當我使用

int x = atoi(example) 

int x = strtol(example, NULL, 16) 

我在這兩種情況下回到零(我期待13)。我錯過了一些基本的東西?

回答

4

atoi將諸如"0"之類的字符串轉換爲其等效數字,在本例中爲0。你有什麼是字符串"\0\0\0\0\0\0\0\r"這是遠不及數字字符。

如果你要解釋你的字節數字(您使用的是x86處理器的情況下),你可以做這樣的事情

char example[4] = {0, 0, 0, 0xd}; 
printf("%d\n", *(uint32_t*) example); 

你會發現,你會得到的218103808代替13 因以小尾數:越遠走得越多,數字就越大。

正如PNG uses big endian你可以簡單地使用be32toh(大端主辦字節序):

uint32_t* n = example; 
printf("%u\n", be32toh(*n) 
+0

+1爲了讀取數據'be64toh(* n)'的最佳方式。注意:[PNG長度字段是32位。](http://www.w3.org/TR/2003/REC-PNG-20031110/#5Chunk-layout) – chux

+0

@chux修正了 – nemo

2

atoistrtol期望文本字符串,而您有一個二進制值的數組。到在陣列中結合單個字節到更大的整數,嘗試類似:

uint32_t x = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; 
1

的atoi等操作上(ASCII)的字符串。
你會得到123的「123」,這是在字節49 50 41 0.
你有什麼是二進制00 00 00 7B ...(好吧,endianess也很重要)。

簡單,但在這種情況下,錯誤的解決方案(忽略字節序):
鑄陣列地址int*,然後得到一個值與*

由於PNG中的整數在任何情況下應該是大端,所以
指針轉換隻適用於大端機器。
作爲便攜式解決方案,用24,16,8,0移位字節並進行二進制化處理。

+2

不要這樣做,因爲它依賴於硬件的結果。 PNG規範應該說明它實際使用的字節順序(假設它使用多個字節)。 – user3303729

+0

這就是爲什麼我寫「我不知道這個PNG數據是什麼」。在此期間查閱:BE。編輯... – deviantfan