[C/C++标准库]_[初级]_[如何实现std::string自己的Format(sprintf)函数]
2015-07-01 10:50
771 查看
场景:
1. C语言有自己的sprintf函数,但是这个函数有个缺点,就是不知道需要创建多大的buffer, 这时候可以使用snprintf函数来计算大小,只要参数 buffer为NULL, count为0即可.
2. 这里实现std::string自己的sprintf也是用了snprintf的特性,先计算大小,再创建空间,之后存入std::string.
3. 还使用了C的可变参数特性.
让我们看看可变参数的声明:
注意: 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
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.
相关文章推荐
- C语言中memset函数详解
- [C/C++标准库]_[初级]_[如何实现std::string自己的Format(sprintf)函数]
- C++中命名空间
- 初探浅拷贝与深拷贝
- itoa不是c语言标准函数
- c++制作小游戏--雷电
- C语言-常用函数处理
- 关于中值滤波算法,以及C语言实现(转)
- 【C语言】统计一个数二进制中1的个数
- 【C语言】用宏实现一个整形奇偶位交换
- 【C语言】求一个数的绝对值
- 【C语言】不使用大小于号,求出两数最大值
- c++ 文件输入输出
- c++ 异常 错误
- C++的异常处理
- C++常用库函数
- C++ 覆盖 重载 隐藏 浅析
- C/C++数据对齐汇总
- OJ第三批——Problem L: C++继承(改错题)
- 浅谈VC++中的内联