2015-06-04 634 views
-1

我想將字節數據(文件正文)轉換爲十六進制以打印它。我已經複製了一個轉換函數,但並不完全理解它。C++ char *到HEX轉換

#include "stdafx.h" 
#include <iostream> 
#include <Windows.h> 
#include <string> 

std::string byte_2_str(char* bytes, int size) { 
    char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B','C','D','E','F'}; 
    std::string str; 
    for (int i = 0; i < size; ++i) { 
     const char ch = bytes[i]; 
     str.append(&hex[(ch & 0xF0) >> 4], 1); 
     str.append(&hex[ch & 0xF], 1); 
    } 

return str; 

} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 

    char data[] = "1"; 
    std::string str = byte_2_str(data, sizeof(data)); 
    std::cout << str << std::endl; 


    system("PAUSE"); 
    return 0; 
} 

什麼是移位(4)和掩碼0xF?它是如何工作的?此外,當我試圖將「1」作爲參數傳遞給func時,它返回3100,但我認爲它會返回0100,因爲1在dec或hex中都是1。我錯了嗎?

+0

'sizeof(data)'是錯誤的,因爲你基本上在你的計算中包含了空字符。你應該使用'strlen(data)'。話雖如此,你在這裏混合C字符串和C++字符串。 –

+0

我知道,我使用char *因爲我有一個字節數組的文件內容(類似於char),因此strlen將不會有用(因爲數組中有\ r \ n個字符) –

+0

*什麼是shift 4)和掩碼0xF用於?*它將'(ch&0xF0)'的結果從位4..7移動到位0..3,大概是這樣可以更容易地訪問它們 –

回答

1

十六進制表示中的一位對應於二進製表示中的四位。

ch & 0xF0屏蔽掉高四位。 >> 4將它們轉換爲低位。

0xAB & 0xF0 -> 0xA0 
0xA0 >> 4 -> 0xA 

ch & 0xF屏蔽掉低四位。

0xAB & 0xF -> 0xB 

原因您意想不到的結果是字符'1'0x31在ASCII編碼(十進制49)。
您正在查找角色的數字表示,而不是其代表的數字。

你會得到預期的結果,如果你做

char data[] = {1}; 
+0

因此,當HEX編輯器使用文件時,這意味着他們編輯ascii代碼的十六進制值或者我沒有得到它? –

+0

@IvanPetrov它們通常會顯示與文件中二進制數據對應的十六進制數字,因此如果文件恰好包含ASCII編碼的文本,它們將顯示文本ASCII編碼的十六進制表示形式。它只是一個二進制 - >十六進制映射,編輯器不關心文件中的數字代表什麼。 – molbdnilo

+0

我現在看到了,再次感謝。 –

1

旁註:

Also, when i'am tried to pass "1" as argument to func, it returns 3100 

這是正確的。該函數需要一個char數組,但對數組作爲原始數據進行操作,而不是將其作爲一組字符。這只是因爲C沒有「字節」類型,並且由於類型保證爲8位,所以它是可以用來表示字節的最方便的類型。

如果您查看ASCII表格,'1'對應於0x31。如果您使用以下內容,然後你會看到你所期望的輸出:

char[] data = {1}; 

正如其他人所說,那麼你得到的0×00後,因爲現有的代碼也包括NULL終止。