我正在处理一个C代码库,我的前任使用了以下代码:
#ifdef _MSC_VER
// Map to equivalent function
#define snprintf sprintf_s
#endif
代码库需要在Linux(gcc/clang),OSX(gcc/clang)和Windows(VS)上编译。我第一次尝试在Visual Studio 2015中编译代码。以前使用的是Visual Studio 2010。我遇到了描述这里的错误,并能够使用已接受答案的线索进行编译:
#ifdef _MSC_VER
#if _MSC_VER<1900
#define snprintf sprintf_s
#endif
#endif
该项目现在可在Visual Studio 2015和OSX上使用clang编译。但是,我对sprintf_s文档中的一条陈述感到担忧:
与snprintf不同,sprintf_s保证缓冲区将以null结尾(除非缓冲区大小为零)。
如果Visual Studio包含符合C99标准的snprintf
版本,那么缓冲区不应该被保证是以null结尾吗?
我写了一个简单的程序来评估这种行为。
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
char buf[5];
snprintf(buf, sizeof(buf), "abcdef");
printf("buffer: %s\n", buf);
printf("size of buffer: %lu\n", strlen(buf));
printf("last character a null terminator?: %s\n",
(strcmp(&buf[4], "\0") == 0) ? "yes" : "no");
return 0;
}
我在OSX和Windows上使用Visual Studio 2015构建和运行了该程序。
在OSX上,输出结果是:
~$c99 main.c
~$./a.out
buffer: abcd
size of buffer: 4
last character a null terminator?: yes
在 Windows 7 上使用 Visual Studio 2015 的情况下,输出结果是
> printf_evaluation.exe
buffer: abcd
size of buffer: 4
last character a null terminator?: yes
这是否表明输出实际上是以null结尾的,并暗示MSDN文档是错误的?我的示例是否太简单了?在使用Visual Studio 2015时,snprintf
的输出是否存在未以NULL结尾的情况?
snprintf()
在Visual Studio中实现的任何异常或错误。 - P.Psnprintf
与C99标准的实现不同,这就是所有这些问题的根源。我不知道Visual Studio运行时是否会更新到使用C99版本。 - M.M_snprintf_s()
而不是sprintf_s()
来避免(人为)崩溃,而且返回值也会是错误的(直到 VS2015,只有_scprintf()
无条件地返回“完整”长度)。 - Medinoc