为什么在msvc ++中我们有_snprintf而其他编译器允许使用snprintf

时间:2012-07-20 12:09:27

标签: c++ visual-c++ printf

“_”是什么意思?为什么微软在开头添加这个标记?

4 个答案:

答案 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)

当微软的C运行时开始支持它时,

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的结果始终为零终止。