在编写程序做LOG的时候,通常是建立一个字符串表,依序把内容放入例如封包数量统计:
Tx:978978 个数据包
Rx:787878 个数据包
C语言中没有像是C++的STL字符串一类方便的容器,我以前指的是数值又有文字的东西其实很苦恼,常常用笨方法来解决:利用<来>atoi实现strcatC++字符串<<的效果。
后来出现,sprintf 更好用,就像 printf 一样,只是把标准输出导向入字符数组。嘿,仍然很好用,只是问题伴随而来,如果存的太忘,会有溢出的问题,能被编译器抓取出来的问题都是小问题,就怕这种运行时错误,超级难调试,而且如果是连续的记录区块,改成其他人的选择仍然不会察觉。
这次snprintf 就应运而生
int snprintf(char *str,size_t size,const char * restrict格式,...)
他可以限制字符的长度,避免溢出。标准用法是
snprintf(str,sizeof(str),"aaaaaaaaaaaaaaaa");
请一定记住的参数要套用sizeof,一来可以避免写死二来是有效避免溢出,而回传的int是预期存入的长度,例如我上面提到的一串a,回传的值就是16。
以前曾看到一种做法可以用snprintf 来实现运行时调整字符串排列长度的效果
char* str;
int size = snprintf( NULL, 0, "aaaaaaaaaaaaa");
str = (char*)malloc(size++);
snprintf( str, size, "aaaaaaaaaaaaa" );
这作法好不好用就见仁见智,我会使用strlen啦,这样比較直覺。另外值得一提的是,与其用strncpy我会更倾向于使用snprintf,原因在于strncpy不会在溢位后自动补上尾的\0,如果自己忘记补,那strncpy跟strcpy的没什么两样,一样会产生bug。