zoukankan      html  css  js  c++  java
  • [C/C++标准库]_[0基础]_[怎样实现std::string自己的Format(sprintf)函数]


    场景:

    1.  C语言有自己的sprintf函数,可是这个函数有个缺点,就是不知道须要创建多大的buffer, 这时候能够使用snprintf函数来计算大小,仅仅要參数 buffer为NULL, count为0就可以.

    2.  这里实现std::string自己的sprintf也是用了snprintf的特性,先计算大小,再创建空间,之后存入std::string.

    3.  还使用了C的可变參数特性.


    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;
    }

    让我们看看可变參数的声明:

    typedef char *  va_list;

    #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并不知道什么时候结束,所以假设设计其它的可变參数的函数,要先传入一个參数个数作为方法參数.

    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

    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.


  • 相关阅读:
    [栈]
    [数据结构实验]学生成绩管理
    [数据结构实验]集合交并
    shapefile 转 geojson 文件类型
    ubuntu sublime text key
    opengl
    c++
    sublime text3 key
    ubuntu安装nvidia驱动
    全球国家svg边界svg
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6758546.html
Copyright © 2011-2022 走看看