// 示例 3-1:在 C 中使用 snprintf 来字符串化某些数据 // void PrettyFormat(int i, char* buf, int buflen) { // 这就是代码,简洁优雅,关键是比以前要安全得多: snprintf(buf, buflen, "%4d", i); }
注意,即便这样做了,仍然还存在另一种出错的可能,即调用者将缓冲区长度搞错了。这意味着跟那些具有资源管理功能的替代方案相比,snprintf 还算不上百分之百地杜绝缓冲区溢出可能性,不过跟 sprintf 相比它显然要安全多了,在“长度是否安全?”这个问题上应该算是合格的。使用 sprintf 没有合适的途径来绝对避免缓冲区溢出,而通过 snprintf,我们则可以(很大程度上)杜绝缓冲区溢出。
注意,snprintf 的一些标准化之前版本的行为稍有不同。尤其是在一个主要实现中,如果输出结果填满或者大于缓冲区容量,缓冲区里的串就不会以 '\0' 结尾。这种情况下,我们的 PrettyFormat() 函数就得稍作调整以应付这种非标准的行为:// 在C中使用一个并不十分遵从C99标准的_snprintf来将数据字符串化 // void PrettyFormat(int i, char* buf, int buflen) { // 这里是代码,简洁优雅,而且安全得多 if(buflen > 0) { _snprintf(buf, buflen-1, "%4d", i); buf[buflen-1] = '\0'; } }
C++11,先前被称作 C++0x,即 ISO/IEC 14882:2011,是目前的 C++ 编程语言的正式标准。它取代第二版标准 ISO/IEC 14882:2003(第一版 ISO/IEC 14882:1998 公开于 1998 年,第二版于 2003 年更新,分别通称C++98 以及 C++03,两者差异很小)。
参考文章:char sa[256]={0}; _snprintf(sa,sizeof(sa),"%s",sb);
错误原因:当 sb 的长度 >= 256 的时候,sa 将没有 '\0' 结尾。
2.char sa[256]; _snprintf(sa,sizeof(sa)-1,"%s",sb);
错误原因:当 sb 的长度 >= 255 的时候,sa 将没有 '\0' 结尾,忘记给 sa 初始化。
3.char sa[256]; _snprintf(sa,sizeof(sa)-1,"%s",sb); sa[sizeof(sa)]=0;
错误原因:最后一行数组越界。
正确的用法:char sa[256]; sa[sizeof(sa)-1]=0; _snprintf(sa,sizeof(sa),"%s",sb); if(sa[sizeof(sa)-1]!=0) { printf("warning:string will be truncated"); sa[sizeof(sa)-1]=0; }
2.
char sa[256]={0}; int result = _snprintf(sa,sizeof(sa),"%s",sb); if(result==sizeof(sa) || result<0) { printf("warning:sting will be truncated"); sa[sizeof(sa)-1]=0; }
个人第二种方法较好!
===============#include <stdio.h> #include <string.h> int main() { char str[5]; memset(str,0,sizeof(str)); int rt = _snprintf(str,3,"%s","abcdefg"); printf("%d\n",rt); printf("%s",str); return 0; }
vc 程序的输出是:
-1 abc
在 Gcc 中,参数 count 是要向 buff 中写入 3 个字符,包括 '\0' 字符。
#include <stdio.h> #include <string.h> int main() { char str[5]; memset(str,0,sizeof(str)); int rt = snprintf(str,3,"%s","abcdefg"); printf("%d\n",rt); printf("%s",str); return 0; }
gcc 程序的输出是:
7 ab
从输出结果可以知道: