场景:html
1. C语言有本身的sprintf函数,可是这个函数有个缺点,就是不知道须要建立多大的buffer, 这时候能够使用snprintf函数来计算大小,只要参数 buffer为NULL, count为0便可.函数
2. 这里实现std::string本身的sprintf也是用了snprintf的特性,先计算大小,再建立空间,以后存入std::string.ui
3. 还使用了C的可变参数特性..net
[cpp] view plaincopyprint?设计
- std::wstring Format(const wchar_t *format,...)
- {
- va_list argptr;
- va_start(argptr, format);
- int count = _vsnwprintf(NULL,0,format,argptr);
- va_end(argptr);
-
- va_start(argptr, format);
- wchar_t* buf = (wchar_t*)malloc(count*sizeof(wchar_t));
- _vsnwprintf(buf,count,format,argptr);
- va_end(argptr);
-
- std::wstring str(buf,count);
- free(buf);
- return str;
- }
让咱们看看可变参数的声明:orm
[cpp] view plaincopyprint?htm
- typedef char * va_list;
[cpp] view plaincopyprint?blog
- #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
-
- #define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
- #define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
- #define _crt_va_end(ap) ( ap = (va_list)0 )
注意: ap会累加,每次调用va_arg都会指向下一个参数,问题就是va_arg并不知道何时结束,因此若是设计其余的可变参数的函数,要先传入一个参数个数做为方法参数.get
snprintf 源码实现是经过计算%的个数来判断参数个数的.源码
参考:
http://blog.csdn.net/echoisland/article/details/6086406
https://msdn.microsoft.com/en-us/library/1kt27hek.aspx
https://msdn.microsoft.com/en-us/library/2ts7cx93.aspx
[plain] view plaincopyprint?
- If buffer is a null pointer and count is zero, len is returned as the count of characters required to format the output, not including the terminating null.
- To make a successful call with the same argument and locale parameters, allocate a buffer holding at least len + 1 characters.