简体   繁体   English

为什么inet_ntoa在printf中调用两次会产生错误的输出?

[英]Why inet_ntoa called twice in printf gives wrong output?

I wrote a code but I am not sure why the last printf gives unexpected result. 我写了一个代码,但我不确定为什么最后一个printf会产生意想不到的结果。 My command line arguments were 12 and 15. The code is as follows: 我的命令行参数是12和15.代码如下:

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

int main(int argc, char *argv[])
{
  struct in_addr adr, adr2;
  int num, num2;

  num = atoi(argv[1]);
  num2 = atoi(argv[2]);

  adr.s_addr = htonl(num);
  adr2.s_addr = htonl(num2);

  printf("%x %x\n", num, adr.s_addr); # c c000000
  printf("%x %x\n", num2, adr2.s_addr); # f f000000

  printf("%s\n", inet_ntoa(adr)); # 0.0.0.12
  printf("%s\n", inet_ntoa(adr2)); # 0.0.0.15
  printf("%s %s\n", inet_ntoa(adr), inet_ntoa(adr2)); # 0.0.0.12 0.0.0.12
  return(0);
}

I expected the final output to be "0.0.0.12 0.0.0.15" but it's not so. 我预计最终输出为“0.0.0.12 0.0.0.15”,但事实并非如此。 Could anyone please help? 有人可以帮忙吗?

The inet_ntoa function returns a pointer to a static buffer. inet_ntoa函数返回指向静态缓冲区的指针。 In this case, the function is called twice as parameters to another function. 在这种情况下,该函数被调用两次作为另一个函数的参数。 The order of evaluation of function parameters is unspecified, so the contents of the static buffer will be whichever one happens to run last. 函数参数的评估顺序是未指定的,因此静态缓冲区的内容将是最后运行的那个。 And since it always returns the same buffer, the same thing will be printed twice. 并且因为它总是返回相同的缓冲区,所以同样的东西将打印两次。

So you can't call a function like this more that once without an intervening sequence point, ie separate statements, short circuit operators such as && or || 因此,如果没有中间序列点,即无法调用这样的函数,即单独的语句,短路运算符(如&&|| , the comma operator, or the ternary operator. ,逗号运算符或三元运算符。

In the case of this particular code, the two separate calls to printf each with a single call to inet_ntoa (as you do in the two prior lines) is the correct way to do this. 在这个特定代码的情况下,两次单独调用printf每次调用inet_ntoa (正如你在前两行中所做的那样)是正确的方法。

Also, if you plan on saving the result of this function someplace, you can't just save the pointer, since the data it points to will change each time inet_ntoa is called. 此外,如果您计划在某个地方保存此函数的结果,则不能只保存指针,因为每次调用inet_ntoa它指向的数据都会更改。 You would need to copy it using strcpy or strdup . 您需要使用strcpystrdup复制它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM