C++ Format

場景:html

1.  C語言有本身的sprintf函數,可是這個函數有個缺點,就是不知道須要建立多大的buffer, 這時候能夠使用snprintf函數來計算大小,只要參數 buffer爲NULL, count爲0便可.函數

2.  這裏實現std::string本身的sprintf也是用了snprintf的特性,先計算大小,再建立空間,以後存入std::string.ui

3.  還使用了C的可變參數特性..net

 

 

[cpp] view plaincopyprint?設計

  1. std::wstring Format(const wchar_t *format,...)  
  2. {  
  3.     va_list argptr;  
  4.     va_start(argptr, format);  
  5.     int count = _vsnwprintf(NULL,0,format,argptr);  
  6.     va_end(argptr);  
  7.   
  8.     va_start(argptr, format);  
  9.     wchar_t* buf = (wchar_t*)malloc(count*sizeof(wchar_t));  
  10.     _vsnwprintf(buf,count,format,argptr);  
  11.     va_end(argptr);  
  12.       
  13.     std::wstring str(buf,count);  
  14.     free(buf);  
  15.     return str;  
  16. }  


讓咱們看看可變參數的聲明:orm

 

 

[cpp] view plaincopyprint?htm

  1. typedef char *  va_list;  

 

[cpp] view plaincopyprint?blog

  1. #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )  
  2.   
  3. #define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )  
  4. #define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )  
  5. #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?

  1. 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.   
  2. To make a successful call with the same argument and locale parameters, allocate a buffer holding at least len + 1 characters.  
相關文章
相關標籤/搜索