【发布时间】:2013-06-27 19:42:43
【问题描述】:
在我的代码(严格的 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 的更好/更智能的方式??
【问题讨论】:
-
你在 C++ 领域,完全停止使用 sprintf。您想要动态构建字符串的可能是 std::stringstream
-
"First of all, print the documentation about "safe/unsafe" functions from MSDN and burn it!" -
vsnprintf()不已被弃用,不要相信 VS,它是 废话。 -
vsnprintf 很容易被误用,提防并非没有道理。
-
不幸的是,vsnprintf_s 文档非常不准确。它声明如果缓冲区为空或计数为 0,它将返回 -1 并设置 errno,但这并不完全正确。如果为缓冲区传递 null,为 sizeOfBuffer 传递 0,为计数传递 0,它将返回 0(前提是您没有将 null 作为格式字符串传递),并且不会设置 errno。此外,如果您传递一个实际缓冲区和一个实际大小但计数为 0,它将返回 -1 但不设置 errno。该文档还指出,如果缓冲区为空或计数为 0,则将调用无效的参数处理程序。也不正确。 1/2
-
我上面描述的工作流都不会调用无效的参数处理程序。文档说明“如果计数 耸耸肩。另外值得注意的是,vsnprintf(不是 _s)的 MSDN 文档指出“如果缓冲区或格式为 NULL,或者如果计数小于或等于零,则这些函数调用无效参数处理程序”。不对。您可以将一个空缓冲区传递给它,它会为您提供所需的长度(减去空终止符)作为返回值。 2/2
标签: c visual-studio-2010 printf