snprintf()总是空终止?

snprintf总是空终止目标缓冲区?

换句话说,这是否足够:

char dst[10]; snprintf(dst, sizeof (dst), "blah %s", somestr); 

还是你必须这样做,如果somestr足够长?

 char dst[10]; somestr[sizeof (dst) - 1] = '\0'; snprintf(dst, sizeof (dst) - 1, "blah %s", somestr); 

我对这个标准所说的和一些stream行的libc可能做的事情都不感兴趣,这不是标准的行为。

正如其他答案所确立的那样:它应该 :

snprintf …将结果写入string缓冲区。 (…)将以空字符结尾,除非buf_size为零。

所以你必须注意的是,你不会传递一个零大小的缓冲区,因为(显然)它不能写零到“无处”。


但是, 要注意的是,微软的库没有一个名为snprintf的函数,但是历史上只有一个名为_snprintf (注意前导下划线)的函数, 它不会追加一个终止的null。 这里是文档(VS 2012,~~ VS 2013):

http://msdn.microsoft.com/en-us/library/2ts7cx93%28v=vs.110%29.aspx

返回值

让len是格式化数据string的长度(不包括终止空值)。 len和count以_snprintf的字节为单位,_snwprintf的宽字符。

  • 如果len <count,那么len字符存储在缓冲区中,一个null结束符被附加,并返回len。

  • 如果len = count,则len字符被存储在缓冲区中, 不会添加null-terminator,并返回len。

  • 如果len> count,则计数字符存储在缓冲区中, 不会添加null-terminator,并返回负值。

(……)

Visual Studio 2015 (VC14)显然引入了符合snprintf函数,但带有前导下划线和空终止行为的传统依然存在:

当len大于或等于count时, snprintf函数通过在buffer[count-1]处放置一个空终止符来截断输出。 (……)

对于除snprintf以外的所有函数,如果len = count,len字符存储在缓冲区中,则不会添加null-terminator (…)

根据snprintf(3)的manpage。

函数snprintf()vsnprintf()str大部分字节(包括结尾的空字节('\ 0'))写入。

所以,是的,如果size> = 1,不需要终止。

根据C标准,除非缓冲区大小为0, vsnprintf()snprintf() null将终止其输出。

snprintf()函数应该等同于sprintf() ,并增加n参数来表示s引用的缓冲区的大小。 如果n为零,则不应写入任何内容,并且s可能是空指针。 否则,n-1以外的输出字节将被丢弃,而不是写入数组,而在实际写入数组的字节的末尾写入空字节。

因此,如果您需要知道要分配多大的缓冲区,请使用零大小,然后可以使用空指针作为目标。 请注意,我链接到了POSIX页面,但是明确地说,标准C和POSIX之间没有任何分歧:

本参考页面上描述的function与ISO C标准一致。 这里描述的要求和ISO C标准之间的任何冲突都是无意的。 本卷的POSIX.1-2008遵循ISO C标准。

警惕vsnprintf()的微软版本。 当缓冲区中没有足够的空间时(它返回-1,标准函数返回所需的长度),它的行为与标准C版本有明显的不同。 微软版本的null在错误情况下终止它的输出,而标准的C版本则不完全清楚。

请注意您使用TR 24731安全function的答案吗? (请参阅Microsoft版本的vsprintf_s() )和Mac解决scheme的 MSDN , 以获取不安全的C标准库函数的安全替代scheme?

一些老版本的SunOS用snprintf做了奇怪的事情,并且可能没有NUL终止输出,并且返回的值与其他人不一样,但是过去10年发布的任何东西都在做C99说。