sprintf,sprintf_s,_snprintf和_snprintf_s之间的区别

sprintf与sprintf_s区别

函数原型:
int sprintf(char *buffer,const char *format [,argument] ...);

int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] ...);


1、sprintf_s对format 中的格式化的字符的有效性进行了检查,而sprintf仅仅检查format 或者缓冲区是否是空指针。如果有错误则返回相应的错误代码。
2、sprintf_s参数sizeOfBuffer是接收格式化字符串的缓冲区的大小。如果,格式化字符串过大,则sprintf_s会返回一个空string和设置无效参数句柄为激活。

3、sprintf_s将格式化字符串存到缓冲区,并在下一个位置填充Null后将格式化字符串未占用的缓冲区(Null之后的Buffer)全部填充为-3,而sprintf却不会填充而是保持缓冲区中未占用的存储位置上的数据。


sprintf_s,_snprintf与_snprintf_s区别

函数原型:
int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] ... );
int _snprintf(char *buffer,size_t count,const char *format [,argument] ... );

int _snprintf_s(char *buffer,size_t sizeOfBuffer,size_t count,const char *format [,argument] ... );


从sprintf与sprintf_s区别可以知道,如果应该输出的字符串的大小已经达到了sizeOfBuffer,那么就溢出了。溢出的情况下,sprintf_s函数把这当做一个错误,会把buffer缓冲区置为一个空字符串""。而count参数的作用是,输出的字符串就算超过缓冲区长度,仍然会有输出,输出字符串被截断到count大小,在这个大小的字符串后面加null-teminate。

这里比较引人注目的是,_snprintf_s为什么在sizeOfBuffer的基础上,还要多加一个count?count似乎是用来控制理想的宽度的。如果得到的字符串超过了count,于是会被截断到count的长度后面再加一个null-teminate。当然,更高优先级的应该是sizeOfBuffer,必须不超过这个大小。当然,如果count被设置成和sizeOfBuffer同样大,或者不合理的更大,那么这个count参数就失去了意义。这时候,如果输出字符串将要达到或者超过sizeOfBuffer,一样导致一个错误,输出缓冲区被置为空字符串。因此,如果希望缓冲区被尽量利用,可以把count参数置为_TRUNCATE,这样的情况下,实际上效果相当于是将count设置为sizeOfBuffer - 1。


总结来说,sprintf_s在缓冲区不够大时会失败,失败时缓冲区中是一个空字符串。

_snprintf不会失败,但是必须注意,如果缓冲区不够大,缓冲区的内容将不是null-teminate的,必须自己注意字符串的结束。

_snprintf_s结合了2者的优点,只要count参数设置合理,函数就不会因缓冲区不够而失败。


所以,在C++中使用这类函数,还是应该尽可能的使用_snprintf_s才好。

版权声明:本文为cz168love原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。