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说。