ButterLover
ButterLover

Reputation: 137

C: Using sprintf( ) to do IP address parse, incorrect value

I was trying to use sprintf() to parse IP address. buf storing a packet received from other host. And the test data in buf is '\0xff'. I expect to see 255.255.255.255 in ip. But what I get is -1.-1.-1.-1 in ip.

char buf[5];
char ip[18];
...
// They all have value 0xff, that is buf[0]=buf[1]=buf[2]=buf[3]='\0xff';
sprintf(ip, "'%d.%d.%d.%d'",buf[0],buf[1],buf[2],buf[3]);

It seems in every byte in buf it is added by one. I think it should be something with the specifier, maybe I should use a specifier for unsigned int. Then I tried %u, %hhd. They are not correct. Anyone knows this? Is it because of the specifier?

Upvotes: 0

Views: 1303

Answers (2)

Petr Skocik
Petr Skocik

Reputation: 60117

This doesn't really answer the question as GrahamS has already answered it well, but you might want to try using the functions and structs of the TCP/IP stack that were made for this kind of thing:

#include <stdio.h>

#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
  /*
   * Using functions and structs that were made for this
   */

  //this is really just a one-member struct with a  uint_32t
  struct in_addr addr;

  //Convert Presenteation to Number (pton) for the AF_INET address family (IPv4)
  inet_pton(AF_INET,"1.2.3.4",&addr);


  //INET_ADDRSTRLEN -- how much space is needed to hold the presentation of an IP4 ip addresss?
  //defined to 16 -- enough to hold 255.255.255.255 with the null terminator
  char buf[INET_ADDRSTRLEN]; 

  //convert back to string
  inet_ntop(AF_INET,&addr, buf, sizeof(buf));

  puts(buf);
    return 0;
}

Upvotes: 3

GrahamS
GrahamS

Reputation: 10350

You have buf declared as a signed char.
You see -1 because 0xFF is 11111111 in binary which is -1 in Two's Complement

Declare buf as an unsigned char instead, like this:

#include <stdio.h>

int main(void)
{
    unsigned char buf[4] = { 0xFF, 0xEE, 0xDD, 0xFF };
    char ip[18];

    sprintf(ip, "%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);

    printf (ip);

    return 0;
}

Depending on your target platform, you might want to look at libraries that do all this for you. For example inet_ntoa(3)

Upvotes: 2

Related Questions