snprintf的输出是否保证在Visual Studio 2015中以空值终止?

时间:2016-01-20 22:48:52

标签: c visual-studio-2015 c99

我正在使用我的前任使用过的C代码库:

#ifdef _MSC_VER
  #if _MSC_VER<1900
    #define snprintf sprintf_s
  #endif
#endif

代码库需要在Linux(gcc / clang),OSX(gcc / clang)和Windows(VS)上编译。我第一次尝试在Visual Studio 2015中编译代码。以前使用过Visual Studio 2010。我遇到了here描述的错误,并且能够使用接受的答案中的线索进行编译:

snprintf

该项目现在使用Visual Studio 2015进行编译并在OSX上进行编辑。但是,我关注sprintf_s文档中的声明:

与snprintf不同,sprintf_s保证缓冲区将以空值终止(除非缓冲区大小为零)。

如果Visual Studio包含符合C99的#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; } 版本,那么该缓冲区是否应该保证以空值终止?

我写了一个小程序来评估行为。

~$c99 main.c
~$./a.out 
buffer: abcd
size of buffer: 4
last character a null terminator?: yes

我使用Visual Studio 2015在OSX和Windows上构建并运行程序。

在OSX上,输出为:

> printf_evaluation.exe
buffer: abcd
size of buffer: 4
last character a null terminator?: yes

在使用Visual Studio 2015的Windows 7上,输出为

snprintf

不能证明输出实际上是以空值终止的,并且表明MSDN文档不正确吗?我的例子太琐碎了吗?是否存在使用Visual Studio 2015终止elem.style.opacity = +!parseInt(elem.style.opacity); 的输出为空的情况?

1 个答案:

答案 0 :(得分:1)

只要第二个参数大于零,

snprintf()总是会终止缓冲区。是的,MSDN文档是错误的。

From C11 standard, snprintf():

  

snprintf函数等效于fprintf,输出除外   写入数组(由参数s指定)而不是a   流。 如果n为零,则不写任何内容,s可能为null   指针。否则,超出n-1的输出字符是   丢弃而不是写入数组,为空字符   写在实际写入的字符末尾   数组。如果在重叠的对象之间进行复制,则   行为未定义。

(强调我的)。