7

In my code (strict C, not C++), I use vsnprintf this way:

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);

But MS Visual C++ (MSVS10) compiler warns:

warning C4996: 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead. 

However, vsnprintf_s does not have the nifty feature that when you pass NULL for the buffer it will describe how much data it would have printed. Instead, it is documented to return -1.

I feel I'm using vsnprintf in a safe manner by determining the necessary size, and that the recommended replacement, vsnprintf_s isn't the same at all.

Am I missing a better / smarter way to use vsnprintf_s??

4

4 回答 4

4

事实证明,这个问题几乎与以下内容完全相同:

计算 sprintf() 缓冲区的大小

答案摘要:

用于_vscprintf确定缓冲区应该有多大,然后用于vsnprintf_s实际填充它。

于 2013-06-28T18:23:55.337 回答
2

VC终于实现了这个标准vsnprintf请参阅永远不可靠的 MSDN

于 2017-09-26T20:52:34.567 回答
0

要获取缓冲区大小,您可以执行以下操作:

size_t 大小 = _vscprintf(格式,argptr);

这里有一个很好的概述vsnprintf vs vsnprintf_s。如果缓冲区或格式参数是空指针,则本质上 vsnprintf_s 返回 E_INVAL 错误。如果不为 null,vsnprintf_s 将写入缓冲区大小,截断超出大小的数据。

于 2019-03-14T16:06:14.297 回答
0

正如@abelenky 建议的那样,我不会说这是一个重复的问题。如果要vsnzprintf_s代替旧的,则vsnprintf需要传递_TRUNCATE(扩展为((size_t)-1))作为count参数(第三个参数)。

https://msdn.microsoft.com/en-us/library/d3xd30zz.aspx

如果存储数据所需的存储空间和终止 null 超过 sizeOfBuffer,则调用无效的参数处理程序,如参数验证中所述,除非 count 为 _TRUNCATE,在这种情况下,写入缓冲区中的尽可能多的字符串,并且 - 1返回。如果在无效参数处理程序之后继续执行,这些函数将缓冲区设置为空字符串,将 errno 设置为 ERANGE,并返回 -1。

于 2018-05-24T05:52:36.080 回答