2014-02-13 44 views
2

我正在存儲IP地址值插入char數組(uint8_t)其大小是4個字節,而不是的,我需要存儲該值成單個整數,如何做到這一點需要一個字符串值存儲到int,而不是4字節大小的字符數組

uint8_t ip[4]; 
    str = "192.168.1.1"; 
    sscanf(str,"%hhu.%hhu.%hhu.%hhu",&ip[0],&ip[1],&ip[2],&ip[3]); 

上述代碼是我用於存儲IP地址值char(uint8_t) array

+0

該格式是什麼? '19216811'? – 2014-02-13 02:22:54

+0

值應該等於** 0xc0a80101 **十六進制值 –

+0

@siva我認爲這就是我的解決方案會給你的......大聲笑現在看到了這個,有趣的是,輸出正是你想要的!很好的問題! –

回答

0

您可能正在尋找inet_pton。或者你可以逃脫這樣的:

uint32_t someint; 
uint8_t *ip = (void *)&someint; 

然後你sscanf

+0

工作,但它存儲的值反向,所以我打印時使用htonl(someint),或使用另一個變量存儲它以正確的方式,例如(** uint32_t anotherint = htonl(someint)** –

+0

@siva如何將訂單更改爲'ip [3],ip [2] ...' – cnicutar

+0

是的,我用它,但它的(htonl)有點familr –

1

即使您的問題已經很難回答,我非常喜歡您的問題,所以我決定爲您解決問題並實施解決方案。希望這能解決你的問題:

/** 
* The problem: 
* 
* 1 9 2 . 1 6 8 . 0 0 0 . 0 0 1 
* 
* How to store this in an int (32 bits)? 
* 
* Hum, let's see: 2^8 = 0-255 (stores values from 0 to 255) 
* 
* 2^(8 + 8 + 8 + 8) = 2^32 = sizeof(int) = 4 => nice! 
* 
* We can store four numbers from 0 to 255 in it, great! 
* 
* 
* Draft of solution: 
* 
* int ipaddress = 0; //0x00000000 
* 
* ipaddress = (192 << 32 - 8*1) || (168 << 32 - 8*2) || (0 << 32 - 8*3) || 1; 
* 
* classA_part = (ipaddress & 0xff000000) >> (32 - 8*1) 
* classB_part = (ipaddress & 0xff0000) >> (32 - 8*2) 
* classC_part = (ipaddress & 0xff00) >> (32 - 8*3) 
* classD_part = ipaddress & 0xff 
* 
* Let's implement shall we?! 
*/ 

初步解決方案:

#define UPPER32 24 
#define UPPER16 16 
#define UPPER8 8 

int main(void) 
{ 
    int ipaddr = 192 << UPPER32 | 168 << UPPER16 | 0 << UPPER8 | 1; //192 168 000 001 

    printf("ip address: %d.%d.%d.%d\n", 
     ((ipaddr & 0xff000000) >> UPPER32) & 0xff, 
     (ipaddr & 0xff0000) >> UPPER16, 
     (ipaddr & 0xff00) >> UPPER8, 
     (ipaddr & 0xff) 
    ); 

    return 0; 
} 

注意,因爲你正在管理的位來控制你如何存儲的東西在其中,你需要的位移回自己在最低有效位的位置,以便你真正得到你的價值觀。

也要注意這個部分((ipaddr & 0xff000000) >> UPPER32) & 0xff這個工程在我的機器上沒有& 0xff,因爲我的機器是64位,並且我的64位整數的擴展信號是0,如果你的機器架構碰巧是32位,那麼這會延長1從第31位到第9位,這是一個負數,所以你的192將是其他的東西,甚至不接近192.

總之,通過使用最終掩碼0xff我們確保沒有什麼比0將在9到31或63(x64)的位中。

順便說一句,這樣做的結果應該是:

ip address: 192.168.0.1 
Program ended with exit code: 0 

持續,請注意,編寫的代碼,因爲它是可奇怪的是一些,不是每個人都想對付位,所以一可以通過簡化我的初始解決方案更優雅的方法,檢查了這一點:

#define UPPER32 24 
#define UPPER16 16 
#define UPPER8 8 

#define IPADDRESS(a,b,c,d) (a << UPPER32 | b << UPPER16 | c << UPPER8 | d) 
#define IPADDRESS_CLASS_A(ip) (((ip & 0xff000000) >> UPPER32) & 0xff) 
#define IPADDRESS_CLASS_B(ip) ((ip & 0xff0000) >> UPPER16) 
#define IPADDRESS_CLASS_C(ip) ((ip & 0xff00) >> UPPER8) 
#define IPADDRESS_CLASS_D(ip) (ipaddr & 0xff) 

#define IPADDRESS_FORMAT  "%d.%d.%d.%d" 
#define EXTRACT_IPADDR(ip)  IPADDRESS_CLASS_A(ip), IPADDRESS_CLASS_B(ip), IPADDRESS_CLASS_C(ip), IPADDRESS_CLASS_D(ip) 

int main(void) 
{ 
    int ipaddr = IPADDRESS(192,168,0,1); //192 168 000 001 
    printf("ip address: " IPADDRESS_FORMAT "\n", EXTRACT_IPADDR(ipaddr)); 
    return 0; 
} 

乾淨的版本看起來更好的權利! 注意,參數a,b,c,d是指ip地址的網絡類別(A,B,C,D類)。

問候。

UPDATE:

是完美的用戶(程序員使用這個)不會有連關於IP地址的格式麻煩比他更應該,所以我加IPADDRESS_FORMAT宏包含字符串與常用的ip地址格式相同;)。

1

試試這個bit-shifting的方法來解析你的陣列到一個單一的內存位置。

uint8_t ip[4]; 
str = "192.168.1.1"; 
sscanf(str,"%hhu.%hhu.%hhu.%hhu",&ip[0],&ip[1],&ip[2],&ip[3]); 

uint32_t ans = ip[0] << 24 + ip[1] << 16 + ip[2] << 8 + ip[3]; 
相關問題