Linux 与 Windows 上 vsnprintf 的区别

问题描述 投票:0回答:1

我在代码中遇到格式问题。问题是这样的:

#include <iostream>
#include <cstdio>
#include <cstdarg>

void PP_p_VSPF_vsprintf(char *buf, size_t max_size, const char *fmt, va_list args )
{
  const int stat = vsnprintf(buf, max_size, fmt, args);

  if(stat >= static_cast<int>(max_size)) // not enough room in buffer
  {
    buf[max_size - 1] = '\0';
  }
  else if (stat < 0)
  {
    buf[max_size - 1] = '\0';
  }
}


void PP_p_SPF_sprintf(char *buf, size_t max_size, const char *fmt, ...)
{
  va_list argptr;
  va_start(argptr, fmt);
  PP_p_VSPF_vsprintf( buf, max_size, fmt, argptr );
  va_end( argptr );
}

int main() {
 char ExpCrcData[100] = "";

 unsigned int crc32Values[] = {0xe870cde0u, 0x1ec5adaeu, 0xcb43101bu};

 for (int i = 0; i < 3; ++i) {

    PP_p_SPF_sprintf(ExpCrcData, 100, "%s0x%08x ", ExpCrcData, crc32Values[i]);

    std::cout << "Download admin string is now: " << ExpCrcData << std::endl;
 }

return 0;
}

使用GNU编译器,

在 Windows 中,我得到输出:

现在下载管理字符串:0xe870cde0
现在下载管理字符串:0xe870cde0 0x1ec5adae
现在下载管理字符串:0xe870cde0 0x1ec5adae 0xcb43101b

在 Linux 中,我得到输出:

现在下载管理字符串:0xe870cde0
现在下载管理字符串:0x1ec5adae
现在下载管理字符串:0xcb43101b

有人可以解释一下这种差异背后的原因吗?

c++ c linux windows g++
1个回答
0
投票

buf
format
不允许重叠。

因此

PP_p_SPF_sprintf(ExpCrcData, 100, "%s0x%08x ", ExpCrcData, crc32Values[i]); 

应该是

PP_p_SPF_sprintf(ExpCrcData+strlen(ExpCrcData), 100-strlen(ExpCrcData), "0x%08x ",  crc32Values[i]);

或者跟踪您在缓冲区中的位置以及还剩下什么。

© www.soinside.com 2019 - 2024. All rights reserved.