c++ - 为什么相同的 vsnprintf 代码在 Windows (MSVC) 和 Unix (Clang) 上输出不同

标签 c++ windows unix printf

在 Unix (Clang 3.8.1) 上,此代码输出:

6: 32

8: a8e

在 Windows (MSVC 19.00.24215.1) 上,此代码输出:

6: 12345

6: a12345e

#include <iostream>
#include <stdarg.h>

static std::string getFormattedString(const char* fmt, va_list ap) {
  int count = vsnprintf(NULL, 0, fmt, ap) + 1;
  std::cout << count << ": ";
  if (count <= 0) { return "unable to format message"; }

  std::string result = std::string(count, '\0');
  if (vsnprintf(&result[0], count, fmt, ap) < 0) { return "error";}

  return result;
}

static std::string getFormattedString(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  std::string result = getFormattedString(fmt, ap);
  va_end(ap);
  return result;
}

int main(int argc, char *argv[]) {
  std::cout << getFormattedString("%d", 12345).c_str() << "\n";
  std::cout << getFormattedString("a%de", 12345).c_str() << "\n";

  return 0;
}

有趣的是,它们都得到了正确的计数,但在我的 Linux 和 OS X 机器上,这段代码输出了错误的结果。这是什么原因造成的?我在某处招致了 UB 吗?

最佳答案

正如@RaymondChen在评论中所说,vsnprintf修改了ap。如果你想重用 va_list,你必须使用 va_copy 制作一个拷贝:

static std::string getFormattedString(const char* fmt, va_list ap) {
    va_list ap2;
    va_copy(ap2, ap);
    int count = vsnprintf(NULL, 0, fmt, ap) + 1;
    std::cout << count << ": ";
    if (count <= 0) { return "unable to format message"; }

    std::string result = std::string(count, '\0');
    if (vsnprintf(&result[0], count, fmt, ap2) < 0) { return "error";}
    std::cout << result.size() << ' ' << strlen(result.c_str()) << '\n';

    return result;
}

这将使用原始列表两次,并产生正确的结果。

关于c++ - 为什么相同的 vsnprintf 代码在 Windows (MSVC) 和 Unix (Clang) 上输出不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41855571/

相关文章:

c++ - 在 C++ 中,有没有办法让 Child 重用 GrandParent 中定义的纯虚函数的 Parent 类实现

c++ - 字符串表编码与 gzip 压缩

c++ - 如何获取 Win32 线程的名称?

python-3.x - 在Windows 7上为Python3安装OpenCV之后,运行时错误R6034

python - 如何通过shell激活PyCharm创建的venv?

iOS:Unix:Mac 从静态库中提取有关受支持架构的信息。如何?

linux:如何通过脚本工具(文件)记录所有操作以保存在日志文件中

c++ - 这与字节序有什么关系吗?

c - Unix 路径搜索 C 函数

c++ - 如何获得重定向路径的实际路径?