码迷,mamicode.com
首页 > 编程语言 > 详细

[C/C++标准库]_[初级]_[如何实现std::string自己的Format(sprintf)函数]

时间:2015-07-01 12:21:10      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:c++   sprintf   snprintf   stdstring   format   


场景:

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/C++标准库]_[初级]_[如何实现std::string自己的Format(sprintf)函数]

标签:c++   sprintf   snprintf   stdstring   format   

原文地址:http://blog.csdn.net/infoworld/article/details/46707485

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!