Unix到Windows:替代vsnprintf来确定长度?

lx.*_*lx. 11 c windows visual-studio-2010

我目前正在将我们的一个Linux库的代码转换为Windows DLL.

在这个库中,我有一个函数,它以printf方式获取最后一个参数(格式字符串,然后是省略号).在这个函数中,我使用vsnprintf格式化提供的参数.因为我想知道我是否可以将最终字符串塞入一个小缓冲区,或者如果我必须为它分配内存,我有兴趣确定格式化字符串的"将是长度".

要做到这一点,我目前正在使用这样的vsnprintf(显然是组成示例代码):

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void foo(const char* fmt, ...)
{
   int len = 0;
   va_list ap;

   va_start(ap, fmt);
   len = vsnprintf(0, 0, fmt, ap);
   printf("len = %d\n", len);
   va_end(ap);
}

int main(void)
{
   foo("12345%s", "67890");
   exit(0);
}
Run Code Online (Sandbox Code Playgroud)

Open Group Base Specifications Issue 6涵盖了此用法:

vsnprintf(char*restrict s,size_t n,const char*restrict format,va_list ap)

[...] vsnprintf()[...]函数应等同于[...] snprintf().

snprintf(char*restrict s,size_t n,const char*restrict format,...)

如果在调用snprintf()时n的值为零,则不应写入任何内容,已写入的字节数n必须足够大,不包括终止空值,并且s可以是空指针.

当我使用/ analyze on在Windows系统(Visual Studio 2010)上编译此代码时出现问题.编译器/分析器给了我以下内容:

test.c(11):警告C6309:参数'1'为空:这不符合'vsnprintf'的函数规范

test.c(11):警告C6387:'参数1'可能是'0':这不符合函数'vsnprintf'的规范:行:7,8,10,11

快速浏览一下vsnprintfMSDN条目给了我:

如果bufferformatNULL,或者count小于或等于零,则这些函数将调用无效参数处理程序,如参数验证中所述.如果允许继续执行,则这些函数返回-1.

奇怪的是,上面的示例仍然在Windows上"按预期"工作(即它返回给我的将要写入的字符数).

但是,由于我不希望这依赖于未指明的东西,我想知道是否有更好的,官方的方法来实现同样的目标,而不必希望在将来的版本中不会破坏.

谢谢你的时间!

lx.*_*lx. 10

Hans Passant在评论中提供的答案:

记录的_vscprintf在Windows上提供此功能,因此不需要依赖"未指定的行为".

  • 它实际上不是"未指明的行为",它的行为与规范相反. (2认同)