在我的代码(严格C,而不是C ++)中,我用这种方式使用vsnprintf:
char* buf = NULL;
size_t sz;
sz = vsnprintf( buf, 0, format, args); // Ask vsnprintf how big a buffer we need
buf = (char*) malloc(sz + 1);
vsnprintf( buf, sz, format, args); // Now actually fill the buffer
/* Use buf in a dialog box... then: */
free(buf);
但MS Visual C ++(MSVS10)编译器警告:
warning C4996: 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead.
但是,vsnprintf_s
使不具有漂亮的功能,当您为缓冲区传递NULL时,它将描述将打印的数据量。相反,它是documented to return -1。
我觉得我通过确定必要的尺寸以安全的方式使用vsnprintf
,并且建议的替换vsnprintf_s
完全不同。
我错过了更好/更聪明的方式来使用vsnprintf_s
??
答案 0 :(得分:3)
原来这个问题几乎完全重复:
Calculating the size of an sprintf() buffer
答案摘要:
使用_vscprintf
计算缓冲区的大小,然后使用vsnprintf_s
实际填充它。
答案 1 :(得分:1)
VC终于实施了标准vsnprintf
。 See the ever unreliable MSDN
答案 2 :(得分:0)
我不会说这是一个重复的问题,正如@abelenky建议的那样。如果您想使用vsnzprintf_s
代替旧版vsnprintf
,则需要将_TRUNCATE
(扩展为((size_t)-1)
)作为count
参数传递(第3个参数) )。
https://msdn.microsoft.com/en-us/library/d3xd30zz.aspx
如果存储数据和终止空值所需的存储超过sizeOfBuffer,则调用无效参数处理程序,如参数验证中所述,除非count为_TRUNCATE,在这种情况下,尽可能多的字符串将适合缓冲区写的和-1返回。如果在无效参数处理程序之后继续执行,则这些函数将buffer设置为空字符串,将errno设置为ERANGE,并返回-1。
答案 3 :(得分:0)
要获取缓冲区大小,可以执行以下操作:
size_t size = _vscprintf(format,argptr);
此处vsnprintf vs vsnprintf_s提供了很好的概述。本质上,如果缓冲区或格式参数为空指针,则vsnprintf_s返回E_INVAL错误。如果不为null,则vsnprintf_s将写入缓冲区大小,并截断超出大小的数据。