Take the 2-minute tour ×

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 get that from a 32 bit integer into a string in it's dotted decimal notation (something like Obviously we can't be using any type of inet functions either...I'm stumped!

share|improve this question
If you are writing code - you should use inet functions - and if I gave the test I would fail you for reinventing working tested code :) –  Mark Nov 5 '09 at 12:52
add comment

6 Answers

up vote 18 down vote accepted

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(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.

share|improve this answer
Thanks a bunch iWerner! –  Kris Richards Nov 5 '09 at 13:09
So wait, let me ask you thinks...how would I go the other way around then? If I had the string, how could I get back the int? –  Kris Richards Nov 5 '09 at 13:22
To get back from the string to the int you would need to parse the string. i.e. no easy bit-hacking way. –  Yuval Adam Nov 5 '09 at 13:36
look here dnsqueries.com/en/ip_v4_converter.php –  gor Jul 4 '12 at 11:54
add comment

You actually can use an inet function. Observe.


#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

share|improve this answer
This is so obviously the best answer. Why doesn't it have the green tick? No need to go re-inventing wheels. –  David Wallace Dec 28 '13 at 23:06
add comment

Hint: break up the 32-bit integer to 4 8-bit integers, and print them out.

Something along the lines of this (not compiled, YMMV):

int i = 0xDEADBEEF; // some 32-bit integer
          (i >> 24) & 0xFF,
          (i >> 16) & 0xFF,
          (i >> 8) & 0xFF,
          i & 0xFF);
share|improve this answer
Uh ... This doesn't compile, is there a function call missing? And the shift counts are all wrong, they seem to think that two hex digits equals four bits. Further, it's better to shift first and mask later, like iWerner. –  unwind Nov 5 '09 at 13:04
Why did this get any votes? –  janm Nov 5 '09 at 13:20
Like I said, it was a quick answer. Fixed the bit-shifting. –  Yuval Adam Nov 5 '09 at 13:34
Oh Boy! Never write something like 0xDEADBEEF, unless you want to find yourself debugging for hours etc. See stackoverflow.com/questions/1556672/… –  RED SOFT ADAIR Nov 5 '09 at 13:52
Still doesn't compile after 5 edits & still has a bug. –  Ray Burns Nov 5 '09 at 13:57
show 1 more comment

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);
share|improve this answer
This isn't portable; it depends on sizeof(unsigned) being 4 (like some other answers) and the byte order within an int. –  janm Nov 5 '09 at 13:24
@janm, of course it's not portable. If there is a need for portable code, we can define alternative IP unions to handle more cpu architectures without modifying the actual code. –  Nick Dandoulakis Nov 5 '09 at 15:06
The bit shifting approaches are portable, no modifying actual code required. Why introduce a bunch of special cases where there is a shorter, clearer, portable version? Performance? On a modern compiler, I'd be surprised if you could measure a difference (although I haven't checked). And you probably want %d instead of %x. –  janm Nov 6 '09 at 0:10
add comment

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;
share|improve this answer
add comment
#include "stdio.h"

void print_ip(int ip) {
   unsigned char bytes[4];
   int i;
      bytes[i] = (ip >> i*8) & 0xFF;

int main() {
   int ip = 0xDEADBEEF;
share|improve this answer
add comment

Your Answer


