类型安全且自动管理内存的返回 std::string 的 sprintf 实现
在这篇博文里,我提到了一个例子,说的是使用C++实现类型安全的printf。这个例子很惊艳,但是在我写程序的时候,并非那么“迫切”地需要它出现在我的工具箱中,因为它并不比普通的printf方便,而且它没有出现的标准库中。所以自己也懒得整。相反,这个函数的兄弟,sprintf,倒是一个非常需要的函数。不仅仅是因为需要它类型安全,而是 sprintf 有比 printf 更多的麻烦:
- 首先它确实也不是类型安全的
- 使用sprintf之前,必须要先准备一段buffer,但这个buffer的大小难以确定,还要防溢出
- C++程序中多数时候我还是需要使用 string,于是还是要再用buffer中的字符串再生成一个string对象来使用。
这非常的麻烦,但是,sprintf 紧凑的表达是它最大的优点~我才不会用流去格式化一个字符串呢,实在是让人精神分裂啊。
想到用 variadic template 实现的 printf 之后,觉得应该是完全可以模仿这个做一个 sprintf 函数的啊,除了得到类型安全的好外之外,还能直接从函数返回字符串,又不会有溢出的问题,string和流自动地把内存管理好。一举多得。
std::string sprintf(const char *s)
{
std::stringstream ss;
_sprintf(ss, s);
return ss.str();
} void _sprintf(std::stringstream & ss, const char *s)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
throw std::runtime_error("invalid format string: missing arguments");
}
}
ss << *s++;
}
} template<typename T,typename... Args>
std::string sprintf(const char *s, T value, Args... args) {
std::stringstream ss;
_sprintf(ss, s, value, args...);
return ss.str();
} template<typename T, typename... Args>
void _sprintf(std::stringstream & ss, const char *s, T value, Args... args)
{ while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
ss << value;
_sprintf(ss, s + 1, args...); // call even when *s == 0 to detect extra arguments
return;
}
}
ss << *s++;
}
throw std::logic_error("extra arguments provided to lyw::sprintf");
}
使用起来也很方便,直接像原来的sprintf一样用就好了。而且如果自定义的对象实现的流操作符重载,就可以自动地与这个函数配合。非常精巧。
string str = sprintf("I tried % times in % ", 10, "Monday");
只需要加一点点代码(使用C++的流控制符),就可以实现各加精细的格式,这个版本我就不再贴了。
PS: 代码在VS2013上跑,很High,
VS2013在C++的开发环境(我是指编辑器)上做了很大的改进,而且速度也快了。算是难得
类型安全且自动管理内存的返回 std::string 的 sprintf 实现的更多相关文章
- iOS 非ARC基本内存管理系列 2-多对象内存管理(3) 利用@property来自动管理内存
iOS 基本内存管理-多对象内存管理(2)中可以看到涉及到对象的引用都要手动管理内存:每个对象都需要写如下代码 // 1.对要传入的"新车"对象car和目前Person类对象所拥有 ...
- Mysql: Connect/C++ 使用过程中发现返回 std::string 造成的内存泄露
在使用 Connect/C++ ,测试时发现在调用 getString 出现了内存增长的情况. ConstructOutput(); //打印出当前内存 ;i<;++i) { prepareSt ...
- Objective C----手动管理内存和自动管理内存
对象的引用计数(Reference Counting) 正常情况下,当一段代码需要访问某个对象时,该对象的引用的计数加1:当这段代码不再访问该对象时,该对象的引用计数减1,表示这段代码不再访问该对象: ...
- iOS手动管理内存
虽然iOS已经有了ARC帮你自动管理内存,但在有些项目中必须采用手动的方式,而且在懂得手动管理内存的情况下会是自己的代码更加完善 众所周知,基于手动管理内存的情况下必然涉及到 relese reta ...
- Oracle DB 自动管理共享内存
• 启用Oracle Enterprise Manager (EM) 内存参数 • 设置自动优化的内存参数 • 使用手动优化的SGA 参数覆盖最小大小 • 使用SGA Advisor 设置SGA_TA ...
- 【超值分享】为何写服务器程序需要自己管理内存,从改造std::string字符串操作说起。。。
服务器程序为何要进行内存管理,管中窥豹,让我们从string字符串的操作说起...... new/delete是用于c++中的动态内存管理函数,而malloc/free在c++和c中都可以使用,本质上 ...
- 根据Facebook内存的管理使用,浅谈在iOS上自动检测内存泄漏问题
分装库下载:https://github.com/facebook/FBMemoryProfiler FBMemoryProfiler类库使用教程:http://ifujun.com/fbmemory ...
- 【深入理解JAVA虚拟机】第二部分.内存自动管理机制.3.垃圾收集器与内存分配策略
1.学习目的 当需要排查各种内存溢出. 内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调节. Java内存运行时区域的各个部分,其中程序计数 ...
- OpenCV 2.4.9 学习笔记(2)—— OpenCV内存自动管理
OpenCV自动内存管理 目前版本的OpenCV是自动处理所有自己的内存的,虽然这么说也不是很严谨.OpenCV在2.0版本中引入了一个新的C++接口,利用自动内存管理给出了解决问题的新方法.使用这个 ...
随机推荐
- Java系列:关于Java中的桥接方法
这两天在看<Java核心技术 卷1>的泛型相关章节,其中说到了在泛型子类中override父类的泛型方法时,编译器会自动生成一个桥接方法,这块有点看不明白. 书上的例子代码如下: publ ...
- REST: C#调用REST API (zz)
由于辞职的原因,最近正在忙于找工作.在这段期间收到了一家公司的上机测试题,一共两道题,其中一道题是关于REST API的应用.虽然在面试时,我已经说过,不懂REST,但那面试PM还是给了一道这题让我做 ...
- 从0开始学Java——JSP&Servlet——如何部署web应用程序
web容器要求应用程序部署时,需要像下面这样组织其目录结构: 手动去创建这样的目录结构还是挺麻烦的,所幸我们有开发工具,所以可以像下面这样来部署一个web项目. 1)确认程序代码已经完成: 2)在ec ...
- [CareerCup] 1.8 String Rotation 字符串的旋转
1.8 Assume you have a method isSubstring which checks if one word is a substring of another. Given t ...
- SQL温故系列两篇(二)
.Sql 插入语句得到自动生成的递增的ID值 Insert into Table(name,des,num) values(’ltp’,’thisisbest’,10); Select @@ident ...
- 阿里面试回来,想和Java程序员谈一谈(转载)
引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容 ...
- iOS7(iPhone4)button不能改变button的title
最近整了个高端的iPhone4测试机,系统是iOS7.1,测出一个问题,两个button,第二个的enable为NO,点击第一个button,第二个的title改变,然而在iPhone4上并不能运行, ...
- hdu1507二分匹配
1 //hdu1507 挺不错的题 #include<stdio.h> #include<string.h> #define INF 99999999 struct node ...
- 如何解决mysql数据库X小时无连接自动关闭
windows下打开my.ini,增加: interactive_timeout=28800000 wait_timeout=28800000 专家解答:MySQL是一个小型关系型数据库管理系统,由于 ...
- json2form已改名为AForm
相信大部分程序员都接触过表单,表单是收集用户输入的不二之选,但是表单的开发又是最繁琐.最复杂的,简单地说,开发表单你需要涉及到很多知识: 布局,表单如何布局排版,看起来最清晰整洁,且符合用户体验 控件 ...