函数声明:
intvsnprintf(char*str,size_t size,const char *format,va_list ap );
关于该函数各个参数的具体意义不再赘述,参见百度百科即可,下面仅对该函数使用过程中的一些细节或者注意点进行说明。
# include stdio.h # include stdarg.h # define maxlen 10 int mon _ log (char * format,) { char str_tmp[MAXLEN]; int i=0,j=0; va_list vArgList; va_start(Varglist,format ); I=vsnprintf(str_tmp,MAXLEN,format,vArgList ); va_end(vArglist; printf('%s”,str_tmp; //黄色高亮部分代码for(j=0; jMAXLEN; j () printf('%d ',str_tmp[j] ); }printf((n ); return i; }void main () intI=mon_log )、%s、%d、%d、%c、' abc '、2、3、'n ' ); //绿色高亮部分代码printf(%d(n ),I ); }输出:
vsnprintf会自动在写入字符的后面加上停止符 。如上,str_tmp最大10个字符,在写入9个字符后,自动添加了 (第二行最后一个ASCII码为0的字符)。由于前9个字符的最后一个是换行符(第二行倒数第二个ASCII码为10的字符),所以黄色高亮部分代码并没有增加换行符打印,但是实际还是有换行效果。
a .将绿色高亮部分的代码替换为:
int i=mon_log(“%s,%d,%d,%c”,”abcd”,2,3, ‘n’);
在这种情况下,换行符不会写入str_tmp,因此黄色高亮部分的代码没有换行符效果。 但是,停止代码会被写入str_tmp。
b .将绿色高亮部分的代码替换为:
int i=mon_log(“%s,%d,%d,%c”,”abcde”,2,3, ‘n’);
停止代码仍然写入str_tmp,但可以观察到最后一个输出从9到11依次增加。 因此,对于返回值,size或大于size的值表示输出到buffer的字符被截断,如果在输出过程中发生错误,则返回负数。 这里的size是10,所以a. b两种方式都已经发生了舍去,在舍去后的剩下的文字中添加停止码的话就会写入数组str_tmp,保证数组不会越界。 也就是说,数组中决定了保留停止代码的位置,实际上可以复制到数组中的字符数为size-1。