2012-06-12 48 views
1

說我有一個地址和像偏移:C程序設計:與strtol()與NUL字節處理

char* base_addr = "\x00\x00\x00\xb7"; 
    char* addr_offset = (user input); 

,我想補充BASE_ADDR和addr_offset在一起。我是否必須編寫自己的strtol()函數,該函數不會在NUL處終止,還是有另一種方法可以成功添加這兩個地址?

編輯:

忘了說這是Linux x86。

+0

我不清楚你到底把你的用戶輸入添加到現有的字符串是什麼意思。但是,基本上,是編寫自己的功能。這應該是微不足道的。 –

回答

0

base_addr實際上是一個32位整數值,恰好是使用字節常量硬編碼的。您應該簡單地將指針的類型轉換爲unsigned long,然後對由用戶輸入的字符串調用strtol(),然後對兩者進行求和。

這是一種使用字符串硬編碼指針的方式。首先,C將在字符串的末尾添加一個NUL字節,所以現在你的32位值需要5個字節,並且添加了填充字節後,最終可能會使用8個字節來存儲指針,正好是所需的兩倍。更好地做到這一點是這樣的:

char base_addr[] = {'\x00', '\x00', '\x00', '\xb7'}; 

更妙的是,只是說你的意思,只要編譯器將讓你做類型轉換:

unsigned char *base_addr = (unsigned char *)0xb7000000; 

我只是檢查,和GCC讓你在沒有錯誤或警告的情況下執

編輯:哦,好吧,真正的問題是如何訪問整數值內的字節。

你應該能夠做到這一點只用指針搞亂:

unsigned long base_adr = 0xb700000000; 
unsigned char *p = (unsigned char *)&base_adr; 

以上技巧可與整數類型。另一種方式來做到這一點是與C聯合:

typedef union 
{ 
    char bytes[4]; 
    unsigned long n; 
    unsigned char *ptr; 
} ADR_WINDOW; 

ADR_WINDOW x; 

x.n = 0xb700000000; 
assert(x.bytes[3] == 0xb7); // on a little-endian computer 
assert(x.bytes[0] == 0xb7); // on a big-endian computer 

工會技巧適用於任何類型,就是做低俗的招數就像是在看一個浮點值內的位的唯一可移植的方法。

+0

如何在將兩者加在一起(我需要它作爲包含小端字節的字符串)後將無符號長字符串返回到字符串中? –

+0

我不認爲這是正確的。你可以將任何東西投射到'char *'。爲什麼它應該和整數和浮點數不同?使用這樣的工會在技術上是未定義的行爲。你應該更喜歡'uintptr_t' /'uint32_t'而不是'unsigned long'。 –

+0

關於'uintptr_t'的好處。但以我的經驗,嘗試訪問浮點內的位是讓GCC抱怨「類型化指針」的一種快速方法。我不確定你對聯合技巧是未定義的行爲是否正確;那是C最接近官方的方式,我發現它是完全便攜的,甚至是DSP芯片。當然,整數值內的字節順序取決於系統的字節順序。 – steveha