12

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

4

4 回答 4

19

全局命名空间中以 开头的标识符_是为实现保留的。_snprintf只是实现(Visual Studio)提供的一个功能。至于这样做的理由,Visual Studio 实现了 C89,并且snprintf是后来的 C99 标准的一部分。

除此之外,两个函数的语义在返回类型上有所不同,返回类型snprintf总是格式化字符串占用的字符数(缓冲区中是否有足够的空间,如果没有则_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 );

您不能这样做,_snprintf因为该函数返回的唯一信息是当前大小不够。

于 2012-07-20T12:30:06.013 回答
12

snprintf()在 Microsoft 的 C 运行时开始支持它时,它还不是标准的一部分。

由于函数原型没有标准化,并且开发人员不想使用该名称snprintf(以防标准后来指定了不同的原型),他们选择添加一个前导下划线来表示该函数是微软对该标准的扩展。

于 2012-07-20T12:22:43.557 回答
3

加上上述,

自 Visual Studio 2015 以来有适当的 C99snprintf()和可用vsnprintf()

他们甚至不会触发众所周知的不安全功能弃用警告。
_snprintf_s()_vsnprintf_s(),虽然提供,是 MSVC 特定功能的“安全变体”,具有非 C99 行为。

于 2016-10-03T16:38:56.950 回答
1

除了在缓冲区不够大的情况下返回值不同(在大卫的回答中描述)之外,组中的函数在另一个重要方面_sn...与标准不同。如果目标缓冲区只有一个字符snprintf太短,则函数将这种情况视为“成功”。_sn...

更详细地说,如果目标缓冲区足够长以存储整个结果序列但没有终止零字符,则_sn...函数不会截断结果,不将终止零写入目标缓冲区并返回缓冲区大小为结果。因此,在一般情况下,不能保证结果为零终止。

在相同的情况下,snprintf将丢弃结果序列的最后一个字符并在其位置写入零终止符。的结果snprintf总是以零结尾。

于 2018-01-21T03:01:56.940 回答