snprintf (或者_snprintf )可以用来只计算长度,如:int c = snprintf(NULL,0,......);
asprintf 第一个参数是指向指针的指针,它会在heap中自动申请空间(最后要手动free)。使用asprintf ,要加上 #define
在 C语言里,要建立一个字符数组的字符串,常常会使用 sprintf() 这个函数来做格式化的处理。但是实际上,这个函式却不是那么「安全」。怎么说呢?sprintf() 的整个界面长的样子的是:
int sprintf ( char * str, const char * format, ...)
函数说明:最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n
函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。
也就是在使用前,必须要先建立好一个字符数组的空间,再用这个函式把内容填入,下面就是简单的例子:
int tmp = 10;
char cstr[20];
sprintf( cstr, "%d * %d = %d", tmp, tmp, tmp * tmp );
在 这个例子里,cstr最后的值,会是「10 * 10 =100」,看起来好像很好?但是如果把 tmp 的值改成 10000 的话,cstr 则应该要变成「10000 * 10000 = 100000000」,但是由于这时候的字符串所需长度为26,而要写入的 cstr 的长度只有20,所以就会造成 buffer overflow 的问题。
像如果是以 Visual C++ 2006来编译的话,如果程序里有用到 sprintf(),他在编译时就会显示一个警告讯息:
warning C4996: 'sprintf': This function orvariable may be unsafe. Consider using sprintf_sinstead.
而要怎么避免 sprintf 的buffer overflow的问题呢?除了微软建议的 sprintf_s() 外,实际上在 C99 里, 也多了一个 snprinf() 是用来取代现有的sprintf()了~他的界面是:
int snprintf(char *str, size_t size, const char *restrict format, ...)
应该可以明显看得出来,snprinf() 这个函式比 sprintf() 多了一个参数 size;这个参数的用处,就是用来限制最大的写入数据量,可以用来避免bufferoverflow。以上面的例子来说,本来写:
int tmp = 10000;
char cstr[20];
sprintf( cstr, "%d * %d = %d", tmp, tmp, tmp * tmp );
的话,会产生 buffer overflow的问题。而如果改成用 snprinf() 的话,就是变成:
int tmp = 10000;
char cstr[20];
snprintf( cstr, sizeof( cstr ), "%d * %d = %d", tmp,tmp, tmp * tmp );
这样一来,snprinf()在把数据写到 cstr时,最多就只会写入20个字符(cstr的长度),而不会有 bufferoverflow 的问题了~
int asprintf(char **strp, const char *fmt, ...);
int vasprintf(char **strp, const char *fmt, va_list
描述
函数
返回值
当成功时,如同