printf和多个字符串的错误行为
Bad behavior with printf and multiple strings
当我将printf/printf_s与两个字符串一起使用时,我会为两个%s变量获得相同的输出。
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));
输出为:
index 11 old: 192.168.1.1 new: 192.168.1.1
现在,我已经通过在print语句之前中断来检查oldip和newip的值是否不同,我还尝试制作以下函数并在print语句中使用它(而不是inet_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);
}
结果是:
192.168.1.1
192.168.1.2
index 11 old: 192.168.1.1 new: 192.168.1.1
为什么我会看到这种行为,我该如何解决
感谢:)
inet_ntoa
重新运行:
一个静态分配的缓冲区,随后的调用覆盖
(这来自Linux手册页。)
您不能在函数中使用它两次,只有第二次调用的输出是可见的(您不知道两次调用中的哪一次是第二次,函数参数的求值顺序未指定)。
执行两个单独的printf
,或者将inet_ntoa
的输出复制到本地缓冲区并输出这些缓冲区。
来自POSIX:
inet_ntoa()的返回值可能指向静态数据,这些数据可能会被随后对inet_ntoa的调用覆盖。
因此,这种行为可能不局限于Linux,并且您不能依赖它而不是覆盖静态缓冲区。
由于Mat描述的原因,在执行下一次调用之前,必须使用对inet_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字符串。因此,当再次调用inet_ntoa
时,它可以自由地覆盖其先前存储的值。
相关文章:
- 由cin中的字符串中未捕获空白引起的分割错误
- 将 GetLastError() 转换为带有错误字符串的异常
- Rapidjson 解析错误:字符串 (207) 中的编码无效
- 尝试对字符串[数组]>>cin 并出现错误(" "字符串下标超出范围")
- 如何检索 DirectX 9 的错误字符串
- 从 C++ => C 包装的 API(多线程)传输错误字符串
- 错误字符串下标超出c++范围
- 获取Openssl证书错误中的错误字符串
- 作为宏参数的安装类型返回错误:字符串常量之前的预期非限定 id
- 语法错误字符串方法C++
- 对于静态错误字符串,哪个的内存/性能效率更高,或者有替代方案
- 使用 strtok() 的错误字符串比较
- C++ 中的运行时错误字符串声明
- 我收到错误:字符串声明上的 C2501
- GCC:为什么一行代码中的错误(字符串和NULL的比较)会导致一长串错误消息
- 错误C2059:语法错误:'字符串'
- 致命错误:字符串:没有这样的文件或目录编译终止
- C++错误:字符串下标超出范围
- 这里面有什么错误?字符串赋值
- 是否有标准的方法来查询EGL错误字符串