[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.
[C/C++标准库]_[0基础]_[怎样实现std::string自己的Format(sprintf)函数]的更多相关文章
- [Zlib]_[0基础]_[使用zlib库压缩文件]
场景: 1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言. 2. zlib比較经常使用,编译也方便,使用它来做压缩吧. MacOSX平台默认支持z ...
- [C/C++标准库]_[0基础]_[交集和补集]
场景: 1. 计算std::vector A和 std::vector B里的同样的元素, 用于保留不删除. 2. 计算std::vector A和 std::vector B里各自的补集, 用于删除 ...
- [libcurl]_[0基础]_[使用libcurl下载大文件]
场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...
- [zlib]_[0基础]_[使用Zlib完整解压zip内容]
场景: 1. 解压文件一般用在下载了一个zip文件之后解压,或者分析某个文件须要解压的操作上. 2. 解压文件,特别是解压带目录的zip文件往往系统没有提供这类Win32 API,当然C#自带库能解压 ...
- [Windows]_[0基础]_[Release程序的崩溃报告minidump解决方式]
场景: 1. Release的程序崩溃时,崩溃报告能够让开发者查明代码哪里出了问题,用处大大的. 2. 仅仅实用VS的编译器才支持,所以MinGW就无缘了. 3. 使用了未处理异常过滤处理函数. 4. ...
- [C/C++11语法]_[0基础]_[lamba 表达式介绍]
场景 lambda 表达式在非常多语言里都有一席之地,由于它的原因,能够在函数里高速定义一个便携的函数,或者在函数參数里直接高速构造和传递. 它能够说是匿名函数对象,一般仅仅适用于某个函数内,仅仅做暂 ...
- [C/C++标准库]_[0基础]_[使用fstream合并文本文件]
场景: 1. 就是合并文本文件,而且从第2个文件起不要合并第一行. 2. 多加了一个功能,就是支持2个以上的文件合并. 3. 问题: http://ask.csdn.net/questions/192 ...
- [C/C++标准库]_[0基础]_[优先队列priority_queue的使用]
std::priority_queue 场景: 1. 对于一个任务队列,任务的优先级由任务的priority属性指明,这时候就须要优先级越高的先运行.而queue并没有排序功能,这时priority_ ...
- [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]
场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...
随机推荐
- RobotFramework自动化3-搜索案例【转载】
本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/robotframework/ 前言 RF系列主要以案例为主,关键字不会的可以多按按F5 ...
- python学习之-- 动态导入模块
python 动态导入模块方法1: __import__ 说明: 1. 函数功能用于动态的导入模块,主要用于反射或者延迟加载模块. 2. __import__(module)相当于import mod ...
- Codeforces 897 A.Scarborough Fair-字符替换
A. Scarborough Fair time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- 牛客网 牛客练习赛7 B.购物-STL(priority_queue)
B.购物 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 在遥远的东方,有一家糖果专卖店 这家糖果 ...
- 以最简单的方式了解--Github
大概是从寒假的时候开始正式的赚取github,从github上面学习一些开源的文档,我记得我注册github账号到现在已经9个月了,但只有最近的2个月才发现github这个新世界,写这篇文章是为了刚入 ...
- Fiddler在fiddler option设置还是抓不了HTTPS包解决办法
1:请在“运行”,即下面这个地方输入certmgr.msc并回车,打开证书管理. 打开后,请点击操作--查找证书,如下所示: 然后输入“fiddler”查找所有相关证书,如下所示: 可以看到,我们找到 ...
- JQuery里面的知识
JQuery是一个javaScript库 JQuery极大的简化了javaScript编程 通过点击 "TIY" 按钮来看看它是如何运行的. 演示JQuery的hide函数,隐藏了 ...
- Oracle提示密码快过期的解决办法
今天在使用ORACLE时报出如下错误:ORA-28002: the password will expire within 7 days================================ ...
- [POI2014]Freight
题目大意: 有两个城镇$A$和$B$,有$n(n\le10^6)$辆车从$A$地出发前往$B$再返回$A$地.两地之间的行驶时间为$s(s\le10^9)$,每辆车从$A$地出发的最早时间是$t_i( ...
- Map泛型集合-输入名字输出成绩
package collection; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import ...