Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C vsnprintf_是不推荐的vsnprintf的合适替代品吗?_C_Visual Studio 2010_Printf - Fatal编程技术网

C vsnprintf_是不推荐的vsnprintf的合适替代品吗?

C vsnprintf_是不推荐的vsnprintf的合适替代品吗?,c,visual-studio-2010,printf,C,Visual Studio 2010,Printf,在我的代码(严格的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 /*

在我的代码(严格的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++(MVS10)编译器警告:

warning C4996: 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead. 
但是,
vsnprintf_s
没有一个漂亮的特性,即当您为缓冲区传递NULL时,它将描述它将打印多少数据。相反,它是

通过确定必要的尺寸,我觉得我正在以安全的方式使用
vsnprintf
,并且推荐的替换品
vsnprintf\u
根本不一样


我是否错过了一种更好/更智能的方法来使用
vsnprintf\u

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

答案摘要:


使用
\u vscprintf
计算缓冲区的大小,然后使用
vsnprintf\u
实际填充它。

VC终于实现了标准
vsnprintf

我不会说这是一个重复的问题,正如@abelenky所说的那样。如果要使用
vsnzprintf\u s
代替旧的
vsnprintf
,则需要传递
\u TRUNCATE
(其扩展为
((size\u t)-1)
)作为
count
参数(第三个参数)

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


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

size\u t size=\u vscprintf(格式,argptr)


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

如果您在C++-land中,请完全停止使用sprintf。动态构建字符串所需的可能是std::stringstream-
vsnprintf()
未被弃用,不要相信VS,它是垃圾。vsnprintf很容易被误用,警惕它并非不合理。不幸的是,vsnprintf的文档非常不准确。它指出,如果缓冲区为null或计数为0,它将返回-1并设置errno,但事实并非如此。如果为缓冲区传递null,为sizeOfBuffer传递0,为计数传递0,则它将返回0(前提是未将null作为格式字符串传递),并且不会设置errno。此外,如果传递一个实缓冲区和一个实大小,但计数为0,则它将返回-1,但不设置errno。文档还声明,如果缓冲区为null或计数为0,则将调用无效的参数处理程序。也不是这样。1/2我上面描述的任何一个工作流都将调用无效的参数处理程序。文件说明“如果对大M公司的任何批评都被否决票批准的话+1我从未说过未实现
vsnprintf
。它总是被实现,但也被标记为不推荐,并给出了
C4996
警告。请向microsoft提交错误报告
vsnprintf
是一个标准函数,没有任何权威机构反对。不是我,但我认为“查看永远不可靠的MSDN”这句话可能赢得了否决票。我几乎跳过了过去10年左右的时间,但在过去的10年左右,如果内存可用的话,MSDN曾经是“永远可靠”的文档。不是没有错误,而是一个更好的。@Sz。见对该问题的评论,指出了一些不准确之处。MSDN也充满了MS nonesense,就像它是标准的一样。另一个例子是,他们认为自己有一个“更安全”的版本(直到几年前,他们的
vsnprintf
甚至都不符合C99)。MSDN可能有所改进(我上次看到它是垃圾),但它仍然充满了非标准的东西,几乎没有什么标准和非标准的迹象(因此不可靠)。