“_”是什么意思?为什么微软在开头添加这个标记?
答案 0 :(得分:18)
以_
开头的全局命名空间中的标识符保留用于实现。 _snprintf
只是实现(Visual Studio)提供的函数。至于理由,Visual Studio实现了C89,而snprintf
是后来的C99标准的一部分。
除此之外,两个函数的语义在返回类型中是不同的,在snprintf
中始终是格式化字符串所占用的字符数(缓冲区中是否有足够的空间,而{如果缓冲区中没有足够的空间,{1}}将返回负数。
也就是说,要为输出分配一个足够大的缓冲区,你可以这样做:
_snprintf
你不能用int size = snprintf( 0, 0, "%s %d\n", str, i );
char * buffer = malloc( size+1 );
snprintf( buffer, size+1, "%s %d\n", str, i );
做到这一点,因为函数返回的唯一信息是当前大小不够。
答案 1 :(得分:11)
snprintf()
还不是标准的一部分。
由于函数原型未标准化,并且开发人员不想使用名称snprintf
(如果标准稍后指定了不同的原型),他们选择添加前导下划线以将该函数表示为是Microsoft的标准扩展。
答案 2 :(得分:3)
添加到上面,
自Visual Studio 2015以来有适当的C99 snprintf()
和vsnprintf()
他们甚至没有触发众所周知的不安全功能弃用警告
_snprintf_s()
或_vsnprintf_s()
虽然已提供,但却是"安全变体"特定于MSVC的函数,具有非C99行为。
答案 3 :(得分:0)
除了缓冲区不够大的情况下的不同返回值(在David的回答中描述),_sn...
组中的函数在另一个重要方面与标准snprintf
不同。如果目标缓冲区只有一个字符太短,_sn...
函数会认为这种情况是成功的"。
更详细地说,如果目标缓冲区足够长以存储整个结果序列但没有终止零字符,则_sn...
函数不会截断结果,不写终止零进入目标缓冲区并返回缓冲区的大小。因此,在一般情况下,结果不能保证为零终止。
在相同的情况下,snprintf
将丢弃结果序列的最后一个字符,并在其位置写入零终止符。 snprintf
的结果始终为零终止。