I\'m preparing for a quiz, and I have a strong suspicion I may be tasked with implementing such a function. Basically, given an IP address in network notation, how can we ge
This is what I would do if passed a string buffer to fill and I knew the buffer was big enough (ie at least 16 characters long):
sprintf(buffer, "%d.%d.%d.%d",
(ip >> 24) & 0xFF,
(ip >> 16) & 0xFF,
(ip >> 8) & 0xFF,
(ip ) & 0xFF);
This would be slightly faster than creating a byte array first, and I think it is more readable. I would normally use snprintf, but IP addresses can't be more than 16 characters long including the terminating null.
Alternatively if I was asked for a function returning a 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;
}
You actually can use an inet function. Observe.
main.c:
#include <arpa/inet.h>
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));
}
The results of gcc main.c -ansi; ./a.out
is
The IP address is 54.208.202.125
Note that a commenter said this does not work on Windows.
My alternative solution with subtraction :)
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] );
}
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
}
Another approach:
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);
Here's a simple method to do it: The (ip >> 8)
, (ip >> 16)
and (ip >> 24)
moves the 2nd, 3rd and 4th bytes into the lower order byte, while the & 0xFF
isolates the least significant byte at each step.
void print_ip(unsigned 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]);
}
There is an implied bytes[0] = (ip >> 0) & 0xFF;
at the first step.
Use snprintf()
to print it to a string.