繁体   English   中英

printf 和多个字符串的不良行为

[英]Bad behavior with printf and multiple strings

当我将 printf/printf_s 与两个字符串一起使用时,两个 %s 变量都得到相同的 output。

IN_ADDR oldIP;
oldIP.S_un.S_addr = iptable[j]->ipAddress;
IN_ADDR newIP;
newIP.S_un.S_addr = adapterTbl->table[i].dwAddr;
printf_s("index %d old: %s new: %s", 
          adapterTbl->table[i].dwIndex, inet_ntoa(oldIP),
           inet_ntoa(newIP));

Output 是:

index 11 old: 192.168.1.1 new: 192.168.1.1

现在,我已经通过在 print 语句之前中断来检查 oldip 和 newip 的值是否不同,并且我还尝试制作以下 function 并在 print 语句中使用它(而不是 .net_ntoa):

char *convertIP (DWORD ip)  
{  
    IN_ADDR *addr = new IN_ADDR;
    memset(addr, 0, sizeof(IN_ADDR));
    addr->S_un.S_addr = (u_long) ip;
    return inet_ntoa(*addr);
} 

output 是:

192.168.1.1
192.168.1.2
index 11 old: 192.168.1.1 new: 192.168.1.1

为什么我会看到这种行为,我该如何解决?
谢谢:)

.net_ntoa重新调整:

静态分配的缓冲区,后续调用会覆盖

(这是来自 Linux 联机帮助页。)

您不能在 function 中使用它两次,只有第二次调用的 output 是可见的(并且您不知道这两个调用中的哪一个是第二次 - arguments 到 function 的评估顺序未指定)。

做两个单独的printf s,或将 .net_ntoa 的.net_ntoa复制到本地缓冲区和 output 那些。

来自POSIX

.net_ntoa () 的返回值可能指向 static 数据,这些数据可能会被后续调用.net_ntoa () 覆盖。

所以这种行为可能不限于 Linux,你不能指望它不会覆盖 static 缓冲区。

由于 Mat 描述的原因,您必须在执行下一次调用之前使用对.net_ntoa的一次调用的结果。

这是一种简单的方法:

IN_ADDR oldIP;
oldIP.S_un.S_addr = iptable[j]->ipAddress;
IN_ADDR newIP;
newIP.S_un.S_addr = adapterTbl->table[i].dwAddr;
std::string s_old(inet_ntoa(oldIP));
std::string s_new(inet_ntoa(newIP));
printf_s("index %d old: %s new: %s", 
      adapterTbl->table[i].dwIndex, s_old.c_str(),
       s_new.c_str());

请注意, string构造函数复制了传入的 C 字符串。 因此,当再次调用.net_ntoa时,它可以自由覆盖其先前存储的值。

暂无
暂无

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

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