2015-04-12 108 views
1

這是我想要設置一段時間的代碼現在,我無法弄清楚爲什麼這不起作用。我用輸入中的sockaddr_in創建了一個簡單的函數。我希望它返回(不打印)包含與sockaddr_in關聯的IP的char *。sprintf打印或返回IP地址的問題

char* get_ip_from_sockaddr(struct sockaddr_in client_addr) 
{ 
int a = (client_addr.sin_addr.s_addr&0xFF); 
int b = (client_addr.sin_addr.s_addr&0xFF00)>>8; 
int c = (client_addr.sin_addr.s_addr&0xFF0000)>>16; 
int d = (client_addr.sin_addr.s_addr&0xFF000000)>>24; 

char* ip[24]; 
int n = sprintf(ip, "%d.%d.%d.%d", a, b, c, d); 
printf("%s", ip); // The IP is correctly printed 
return ip; 
} 

我檢索IP這樣的:

char* ip = get_ip_from_sockaddr(client_addr); 
printf("IP CLIENT: %s\n", ip); 

這裏是我PROGRAMM的輸出:

127.0.0.1IP CLIENT: ����� 

我不明白爲什麼這是正確的函數內部打印,但當我從功能檢索IP不打印。

+1

有這樣做的標準函數 - ['inet_aton'](http://linux.die.net/man/3/inet_aton)。 – myaut

+0

我不明白。你爲什麼使用數組char *來存儲IP地址? – madz

回答

3

您已聲明IP爲指針的數組,而不是char數組。但更根本的是,它是一個存在於堆棧上的本地數組,當你從函數返回時,內存被釋放並且可以被任何東西覆蓋。

如果聲明IP作爲

static char ip[24]; 

,你應該是安全的。有一點需要注意:所有對該函數的調用都將使用相同的內存作爲ip字符串,因此一次調用的結果將被下一次調用覆蓋。

+0

感謝您的回覆;但是當我返回函數時,我仍然返回ip,然後影響到主函數中的變量ip。我不太明白這一點。遵循你的建議,我把'char [24] ip;'而不是'char * ip [24];'給出了預期的結果。 – philippe

+1

我想你的意思是'char ip [24]'但這不是安全的,這個內存只在函數執行時被分配,隨後可以被「垃圾」覆蓋,實際上它幾乎肯定會。您還需要聲明它爲「靜態」,這意味着它將被預先分配給一個固定位置。 –