【问题标题】:Replacement for MS _vscprintf on MacOS/Linux?在 MacOS/Linux 上替换 MS _vscprintf?
【发布时间】:2016-02-18 12:49:22
【问题描述】:

作为学习经验,我正在将一些东西从 Windows 移植到 MacOS,并遇到了这样的事情:

void SomeClass::someFunction(const char* format, va_list args)
{
    int size = _vscprintf(format, args); // length after formatting
    std::string s;
    s.resize(size);
    vsprintf(&s[0]);
    ...
}

现在,由于 _vscprintf 是 Microsoft 特定的,我在 Linux 上没有找到类似的东西,我想我会在这里问。

我们还假设这段代码处于某个关键路径中,并且不应该有一些额外的堆分配等开销。

在 MacOS/Linux 上推荐的 _vscprintf 替代品是什么?

谢谢!

【问题讨论】:

  • 可能无法直接替代_vscprintf函数;但如果您将它与vsprintf 一起使用(如在您的someFunction 示例中),您可以改用asprintf 函数(如果它在您的系统上可用)。

标签: c++ string


【解决方案1】:

您可以改用vsnprintf;

  int _vscprintf (const char * format, va_list pargs) { 
      int retval; 
      va_list argcopy; 
      va_copy(argcopy, pargs); 
      retval = vsnprintf(NULL, 0, format, argcopy); 
      va_end(argcopy); 
      return retval; 
   }

感谢@dbasic 提供了更完整的解决方案,感谢@j-a 修复了明显的错误。

【讨论】:

  • 同上。不仅如此,对此的合理期望是崩溃
  • vsnprintf(NULL, 0, f, a); 应该可以代替(这恰好是丹尼尔上面列出的问题的答案)。
  • 我还想补充一点,必须使用 va_copy 复制 a ,否则在后面的函数调用中将不起作用。我在 Mac OS X 上遇到过这样的问题。
  • 我是按以下方式做的: int _vscprintf (const char * format, va_​​list pargs) { int retval; va_list 参数复制; va_copy(argcopy); retval = vsnprintf(NULL,0,格式,pargs); va_end(argcopy);返回 retval; }
  • 有人测试过这个吗?似乎最好的办法是创建一个初始缓冲区,将其作为 vsnprintf 的第一个参数传递,然后
【解决方案2】:

之前的解决方案还可以,但有两个错误:

  1. 函数va_copy 有一个参数,而不是两个参数。
  2. 对函数vsnprintf 的调用不使用argcopy 变量;如果您再次调用vsnprintf,它会在堆栈中产生损坏。
int _vscprintf (const char * format, va_list pargs)
{ 
    int retval; 
    va_list argcopy;
    va_copy(argcopy, pargs); 
    retval = vsnprintf(NULL, 0, format, argcopy); 
    va_end(argcopy); 
    return retval;
}

【讨论】:

猜你喜欢
  • 2017-02-24
  • 1970-01-01
  • 2012-05-31
  • 1970-01-01
  • 2011-04-07
  • 2015-05-18
  • 1970-01-01
  • 2017-10-28
  • 2020-10-11
相关资源
最近更新 更多