2013-08-28 22 views
3

因此,我正在編寫一個非常小而簡單的程序,它將一個數字作爲輸入,將其轉換爲十六進制,並一次打印出兩個字符。C - 在十六進制中打印出一個字符指針會給我奇怪的結果

對於某些數字,它會在輸出前打印出ffffff。

這是我的代碼:

//Convert the input to an unsigned int 
unsigned int a = strtoul (argv[1], NULL, 0); 
//Convert the unsigned int to a char pointer 
char* c = (char*) &a; 

//Print out the char two at a time 
for(int i = 0; i < 4; i++){ 
    printf("%02x ", c[i]); 
} 

大部分輸出的是罰款,看起來像這樣:

./hex_int 1 

01 00 00 00 

但對於一些數字輸出看起來是這樣的:

./hex_int 100000 

ffffffa0 ffffff86 01 00 

如果你刪除所有的f的轉換是正確的,但我不明白爲什麼它只在一些輸入這樣做。

任何人有任何想法?

+1

可能重複[爲什麼printf在打印十六進制時不打印一個字節?](http://stackoverflow.com/questions/3555791/why-does-printf-not-print-out-just-one-byte-when-printing-hex) –

+0

不是你的問題的原因,但因爲'strtoul '返回一個'unsigned long',你可能應該聲明'a'是'unsigned long',即使在你的處理器上它可能有或者可能不是相同的大小。 – lurker

+0

@mbratch - 爲了一致性,這是一個好主意,但可能不是絕對必要的。從'unsigned long'到'unsigned int'的轉換是非常明確的。 –

回答

4

您的參數和打印格式不匹配。默認參數促銷會導致您的char參數(c[i])被提升爲int,該符號延伸(顯然您的char是一種簽名類型)。然後你告訴printf通過使用%x格式將該參數解釋爲unsigned int。繁榮 - 未定義的行爲。

用途:

printf("%02x ", (unsigned int)(unsigned char)c[i]); 

相反。

+0

我也意識到可以通過將c聲明爲unsigned char *而不是char *來解決問題(我認爲)。感謝您的快速回應。 – billg118

+1

使用'unsigned char'可能會給你正確的輸出,但它仍然是未定義的行爲。參數升級仍然是未修飾的'int'。 –

+0

直接轉換爲'unsigned int'將避免未定義的行爲,但您仍然可能在負的'char'值上得到'ffffff'「前綴」。 –

0

char默認情況下在您的系統上簽名。將一個int移入它會使編譯器認爲您想要將最高位用作需要轉換爲int的操作的符號位。並以十六進制數字打印它是一個。

使字符指針cunsigned char *和問題將消失。

如果卡爾是對他的評論(我要去檢查),請使用此故障安全,而不是方法:

printf("%02x ", c[i] & 0xff); 
+0

嚴格來說,使用'unsigned char *'仍然會在print語句中導致未定義的行爲。 –

+0

您所做的更改並未解決該問題。 UB是由默認參數提升將該值轉換爲「int」,然後使用「%x」打印「unsigned int」引起的。你的'&'也會發生同樣的情況。 –

+0

所以它需要'printf(「%02x」,((int)c [i])&0xff);'? (可能括號過多,但現在我要破產了!) – usr2564301

-1

我在那裏做了一會兒,我意識到,你可以看到在一個進程EXE圖像,使用debuger,代碼是所有的權利,但我不能一時通過本機代碼彙編,但遠,用指針一切皆有可能

include stdio.h 

include windows.h 

int main() 

{ 

int i=0; 

char * p = (char *)0x400000; 

for(int i = 0; i < 20; i++) 

{ 

    printf("%p %02x \n",p+i, (unsigned int)(unsigned char)*(p+i)); 
} 

} 
+1

這與OP的問題如何相關? P.S.1。 '(unsigned int)'強制轉換是不必要的。 P.S.2。內存地址0x400000不能保證可讀。是的,它可能通常在Windows x86中(因爲你提到過'windows.h'),但是請注意,這個問題被標記爲「C」而沒有引用任何特定的操作系統或平臺。 – dxiv

-2

好,窗戶.h被添加來使用一些系統調用,我省略了這個例子中的那些,因爲不需要使用cod中的那些e下面,關於unsigned,是的,它可以被忽略,導致char總是> 0,關於地址,正如你之前說的,0400000是exe的頭文件,在這種情況下是「mz」頭文件,但是dll的代碼的過程中可能是7c911000,和DLL另一地址的首標,等..,這個信息來源是exe文件內,並且必須readed爲具有和在何處加載的圖像是在負載主要存儲器的想法,但是當你只有一個進程,是你有更多的,則必須使用系統調用來知道哪裏是第二個過程中,如果一個地址信息無法讀取,只是讀德exe文件在一個記事本,該地址只是一個例子

+1

請在回答問題之前閱讀幫助頁面。這基本上是對你的答案的評論,而不是一個答案。另外你的其他答案不在問題的範圍內。 – rfkortekaas

+0

什麼?,你讀過的線程標題?,打印在十六進制等,這是這裏的主要主題,billg118打開此線程,我張貼和比卡爾altenative代碼,我沒有做一個paralel對話框或wathever,我的回答是在問題的範圍內,因爲我發佈了代碼,而不是談論問題,談論主線程在本論壇的範圍內,或者不是? – dbg