整数到IP地址 – C.

我正在准备一个测验,我怀疑我可能会负责实现这样的function。 基本上,给定一个网络符号的IP地址,我们如何从一个32位整数到它的点分十进制表示法(如155.247.182.83)…? 显然我们也不能使用任何类型的inet函数……我很难过!

这是一个简单的方法: (ip >> 8)(ip >> 16)(ip >> 24)将第2,第3和第4个字节移动到低位字节,而& 0xFF隔离最少每一步都有重要字节。

 void print_ip(int ip) { unsigned char bytes[4]; bytes[0] = ip & 0xFF; bytes[1] = (ip >> 8) & 0xFF; bytes[2] = (ip >> 16) & 0xFF; bytes[3] = (ip >> 24) & 0xFF; printf("%d.%d.%d.%d\n", bytes[3], bytes[2], bytes[1], bytes[0]); } 

有一个隐含的bytes[0] = (ip >> 0) & 0xFF; 在第一步。

使用snprintf()将其打印到字符串。

你实际上可以使用inet函数。 观察。

main.c中:

 #include  main() { uint32_t ip = 2110443574; struct in_addr ip_addr; ip_addr.s_addr = ip; printf("The IP address is %s\n", inet_ntoa(ip_addr)); } 

gcc main.c -ansi; ./a.out的结果gcc main.c -ansi; ./a.out gcc main.c -ansi; ./a.out

IP地址是54.208.202.125

请注意,评论者说这不适用于Windows。

另一种方法:

 union IP { unsigned int ip; struct { unsigned char d; unsigned char c; unsigned char b; unsigned char a; } ip2; }; ... char ips[20]; IP ip; ip.ip = 0xAABBCCDD; sprintf(ips, "%x.%x.%x.%x", ip.ip2.a, ip.ip2.b, ip.ip2.c, ip.ip2.d); printf("%s\n", ips); 

提示:将32位整数分解为4个8位整数,并将其打印出来。

根据这一点(未编译,YMMV):

 int i = 0xDEADBEEF; // some 32-bit integer printf("%i.%i.%i.%i", (i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF); 

这是我要做的,如果传递一个字符串缓冲区来填充,我知道缓冲区足够大(即至少16个字符长):

 sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, (ip ) & 0xFF); 

这比首先创建一个字节数组略快,我认为它更具可读性。 我通常会使用snprintf,但IP地址长度不能超过16个字符,包括终止空值。

或者,如果我被要求返回一个char *的函数:

 char* IPAddressToString(int ip) { char[] result = new char[16]; sprintf(result, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, (ip ) & 0xFF); return result; } 
 #include "stdio.h" void print_ip(int ip) { unsigned char bytes[4]; int i; for(i=0; i<4; i++) { bytes[i] = (ip >> i*8) & 0xFF; } printf("%d.%d.%d.%d\n", bytes[3], bytes[2], bytes[1], bytes[0]); } int main() { int ip = 0xDEADBEEF; print_ip(ip); } 

我的替代解决方案减法:)

 void convert( unsigned int addr ) { unsigned int num[OCTET], next_addr[OCTET]; int bits = 8; unsigned int shift_bits; int i; next_addr[0] = addr; shift_bits -= bits; num[0] = next_addr[0] >> shift_bits; for ( i = 0; i < OCTET-1; i ++ ) { next_addr[i + 1] = next_addr[i] - ( num[i] << shift_bits ); // next subaddr shift_bits -= bits; // next shift num[i + 1] = next_addr[i + 1] >> shift_bits; // octet } printf( "%d.%d.%d.%d\n", num[0], num[1], num[2], num[3] ); } 

从string到int和back

 const char * s_ip = "192.168.0.5"; unsigned int ip; unsigned char * c_ip = (unsigned char *)&ip; sscanf(s_ip, "%hhu.%hhu.%hhu.%hhu", &c_ip[3], &c_ip[2], &c_ip[1], &c_ip[0]); printf("%u.%u.%u.%u", ((ip & 0xff000000) >> 24), ((ip & 0x00ff0000) >> 16), ((ip & 0x0000ff00) >> 8), (ip & 0x000000ff)); 

%hhu指示sscanf读入unsigned char指针; ( 用scanf读取小int )


来自glibc的inet_ntoa

 char * inet_ntoa (struct in_addr in) { unsigned char *bytes = (unsigned char *) ∈ __snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); return buffer; } 
 void ul2chardec(char*pcIP, unsigned long ulIPN){ int i; int k=0; char c0, c1; for (i = 0; i<4; i++){ c0 = ((((ulIPN & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8))) / 100) + 0x30; if (c0 != '0'){ *(pcIP + k) = c0; k++; } c1 = (((((ulIPN & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8))) % 100) / 10) + 0x30; if (!(c1 =='0' && c0=='0')){ *(pcIP + k) = c1; k++; } *(pcIP +k) = (((((ulIPN & (0xff << ((3 - i) * 8)))) >> ((3 - i) * 8))) % 10) + 0x30; k++; if (i<3){ *(pcIP + k) = '.'; k++;} } *(pcIP + k) = 0; // pcIP should be x10 bytes 

}