【问题标题】:inet_ntoa gives the same result when called with two different addresses当使用两个不同的地址调用时,inet_ntoa 给出相同的结果
【发布时间】:2018-02-15 03:37:38
【问题描述】:
//
char ip1[] = "127.0.0.1";
char ip2[] = "211.100.21.179";
printf("ip1: %s\nip2: %s\n", ip1, ip2);

// 
long l1 = inet_addr(ip1);
long l2 = inet_addr(ip2);
printf("ip1: %ld\nip2: %ld\n", l1, l2);

//
struct in_addr addr1, addr2;
memcpy(&addr1, &l1, 4);
memcpy(&addr2, &l2, 4);
printf("%u\n", addr1.s_addr);
printf("%u\n", addr2.s_addr);

//
printf("%s\n", inet_ntoa(addr1));
printf("%s\n", inet_ntoa(addr2));

//
printf("%u,%s\n", addr1.s_addr, inet_ntoa(addr1));
printf("%u,%s\n", addr2.s_addr, inet_ntoa(addr2));
printf("%s <--> %s\n", inet_ntoa(addr1), inet_ntoa(addr2));

输出是:

ip1: 127.0.0.1
ip2: 211.100.21.179
ip1: 16777343
ip2: 3004523731
16777343
3004523731
127.0.0.1
211.100.21.179
16777343,127.0.0.1
3004523731,211.100.21.179
211.100.21.179 <--> 211.100.21.179    // why the same??

我知道printf从右到左解析arg或反之亦然是依赖于平台的,但是为什么输出是相同的值,请帮忙解释一下。

【问题讨论】:

    标签: c printf


    【解决方案1】:

    来自 Linux 手册页:https://linux.die.net/man/3/inet_ntoa

    inet_ntoa() 函数将 Internet 主机地址转换为 按网络字节顺序,转换为 IPv4 点分十进制表示法的字符串。 字符串在静态分配的缓冲区中返回,该缓冲区 后续调用将覆盖。

    看来inet_nota() 的两个调用共享一个缓冲区,因此调用该函数两次会覆盖缓冲区中的内容并将其替换为下一次调用,因此您会得到相同的输出

    【讨论】:

      【解决方案2】:

      inet_ntoa() 使用内部缓冲区将地址转换为字符串。每次调用它时,它都会用新地址重写同一个缓冲区。所以对inet_ntoa() 的两个调用都返回相同的指针,因此printf() 会打印两次相同的字符串。 inet_ntoa() 这样做是为了让您不必在每次调用它时都free() 一个字符串。如果你希望你的输出看起来像你期望的那样,你可以这样做:

       printf("%s <--> ", inet_ntoa(addr1))
       printf("%s\n", inet_ntoa(addr2));
      

      这样printf() 将在第二次调用inet_ntoa() 覆盖之前打印第一个地址。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-21
        • 2012-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多