C++字符串格式化库:CPPFormatLibrary
这个是很久之前写的,去年总结了一下,将其单独提取出来,作为一个开源库放到了GitHub上,然而CPPFormat之类的名字都已经被抢注了,结果只好注册了一个这么蛋疼的名字:CPPFormatLibrary,以下简称FL。
首先介绍一下这是个什么东西。我们知道,在C++当中要进行格式化字符串,通常采用的是C库函数sprintf或者C++的stringstream,然而两者都有自己的问题,比如C库函数的类型安全问题,sprintf当参数不足,或者参数类型与格式化字符不符是都会发生错误,导致崩溃;而stringstream的效率又明显不行。除此之外,我么还知道boost库有format可以用,然而它效率不高。另外还有国外的大神写过fastformat库,地址:http://fastformat.sourceforge.net/ 。它的问题在于过于庞大,集成不方便,会引入太多你并不需要的东西;同时,它也并未将性能发挥到极限。我写这个FL库最初的灵感也来自于fastformat,也特别感谢它。
FL与fastformat一样,都致力于解决前面所描述的C++字符串格式化的各种问题,最终采用的方案是.net方案,关于.net的格式化字符串,可以看这篇文章:http://www.cnblogs.com/zyh-nhy/archive/2007/10/11/921240.html 与fastformat想比,FL移除了一些并没有什么用的功能,并进行了功能增强,比如fastformat并不支持{0,5}这样的更细的描述,而FL支持。当然fastformat与FL都没有完全覆盖.net的format,也就是说并不完全等同于.net的格式化,部分功能并未得到支持。
下面是FL中的测试代码,这个代码展示了最基本的格式化功能:
// Test
#include "Format.hpp" #include "Format/ProgressTimer.hpp" #define TEST_PERFORMANCE_IN_TOOLS 0 using namespace FormatLibrary; #include <iostream>
#include <vector>
using namespace std; void TestProfile()
{
const int TEST_COUNT = ; {
Profile::ProgressTimer Timer("FL"); for (int i = ; i < TEST_COUNT; ++i)
{
string str;
StandardLibrary::FormatTo(str, "{0}--#--{1,8}--#--{2}", , -40.2f, " String ");
StandardLibrary::FormatTo(str, "{0}--#--{1,8}--#--{1}", , -40.2f);
StandardLibrary::FormatTo(str, "{0}--#--{1,8}--#--{3}", , -40.2f, std::string("xxx"));
}
} #if !FL_COMPILER_MSVC
#define sprintf_s sprintf
#endif #if !TEST_PERFORMANCE_IN_TOOLS
{
Profile::ProgressTimer Timer("CL"); for (int i = ; i < TEST_COUNT; ++i)
{
string str;
char szBuf[];
sprintf_s(szBuf, "%d--#--%8.2f--#--%s", , -40.2f, " String ");
str = szBuf;
sprintf_s(szBuf, "%d--#--%8.2f--#--%f", , -40.2f, 0.0f);
str = szBuf;
sprintf_s(szBuf, "%d--#--%8.2f--#--%%f", , -40.2f);
str = szBuf;
}
}
#endif
} #if FL_PLATFORM_HAS_CPP11 && (FL_COMPILER_MSVC||FL_PLATFORM_MACOS)
#include <thread> void TestProfileMultiThread()
{
std::thread t0( TestProfile );
std::thread t1( TestProfile );
std::thread t2( TestProfile ); t0.join();
t1.join();
t2.join();
}
#endif int main()
{
StandardLibrary::STLGlobalPatternStorageA Storage;
Utility::TAutoString<char> TestStr; const char* pszTest = "{0},xxxd{1:d2}={2,3:d2} !! {{}} {0,-5:d8}";
Storage.LookupPatterns(pszTest, strlen(pszTest)); std::string str;
StandardLibrary::FormatTo(str, "test{0}", ); StandardLibrary::FormatTo(str, "{0}", char('c'), short()); #if FL_COMPILER_MSVC
StandardLibrary::FormatTo(str, "0x{0:x}", , DWORD());
#endif std::wstring wstr;
StandardLibrary::FormatTo(wstr, L"Test{1}, {2:f4}, {0}, {0,4}", L" X ", , -10.005f); cout << str << endl;
wcout << wstr << endl; TestProfile(); #if FL_PLATFORM_HAS_CPP11 && (FL_COMPILER_MSVC||FL_PLATFORM_MACOS)
TestProfileMultiThread();
#endif return ;
}
Windows Visual Studio 2013 Release下的输出:
0x64
Test20, -10.0050, X , X
0x64
Test20, -10.0050, X , X
FLElapse:0.0762746
CLElapse:0.269722
FLElapse:0.0756153
FLElapse:0.0766446
FLElapse:0.0762051
CLElapse:0.285714
CLElapse:0.288648
CLElapse:0.289193
Mac Xcode Release:
Test20, -10.0050, X , X
FLElapse:0.0901681
CLElapse:0.19329
FLElapse:0.147378
FLElapse:0.150375
FLElapse:0.153342
CLElapse:0.303508
CLElapse:0.308418
CLElapse:0.307407
这只是一个简单的测试,结果并不能覆盖所有情况,然而可以明确的是,FL在提供了:编译期类型安全检查,不定参数,多线程支持,可重入,可乱序等功能的前提下,并不会比C库函数sprintf慢。因此可以认为在使用C++的情况下,始终应该使用FL代替传统的各种格式化字符串的方式以获取更好更安全的代码。
FL被设计成Header Only的库,这样用起来就更方便了,只需要简单的包含Format.hpp头文件即可获取到所有的功能。同时针对C++ 11做了专门的优化,使得在支持C++ 11的编译器上可以取得更快的运行速度,这是其它库无法比拟的。
如果你使用的是STL的字符串string或者wstring,那么FL已经内置了对应的支持,所有的适配器都已经默认提供。假如你不是使用的STL,比如UnrealEngine中使用的FString,那么你也可以非常容易的集成FL到自己的项目中。UnrealEngine的FString在集成了FL之后,会多出一个静态的FormatTo函数和一个Format成员函数,它们可以用于使用.net风格产生一个字符串或者直接格式化自己。在项目中也可以找到UnrealEngine的集成代码,非常简单。
FL已经成功使用Visual Studio,XCode和Codeblocks with gcc进行编译,并支持windows,macos,linux,ios等平台。已经成功用于多个项目。
项目地址:https://github.com/sczybt/CPPFormatLibrary
使用git Clone地址:https://github.com/sczybt/CPPFormatLibrary.git
你也可以直接Download zip
另外,一个代码库不可能没有bug,如果你发现了问题,可以将测试用例发给我,我会修复之。欢迎大家来使用。
接下来我会针对这个库提供更多的说明和指导文档。
2015.10.15
CPPFormatLibary提升效率的优化原理
关于优化策略的相关讨论:http://www.cnblogs.com/bodong/p/4800340.html
C++字符串格式化库:CPPFormatLibrary的更多相关文章
- C++的字符串格式化库
这里向大家介绍一个C++的字符串格式化库,叫cpptempl,这个库支持对字符串格式的条件,循环,变量插入.看上去很不错,只不过其是基于boost库的. 下面是一个例子: 1 2 3 4 5 6 7 ...
- boost::format(字符串格式化库)
这段时间学习boost库的使用,撰文一方面留以备用,另一方面就是shared精神. format主要是用来格式化std::string字符串以及配合std::cout代替C语言printf() 使用f ...
- (二)boost库之字符串格式化
(二)boost库之字符串格式化 程序中经常需要用到字符串格式化,就个人而言还是比较倾向于C格式的输出,如果只是打印日志,printf就够了,如果到生成字符串,获取你可以选择sprintf,但这些都是 ...
- Lua 中的string库(字符串函数库)总结
(字符串函数库)总结 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-11-20我要评论 这篇文章主要介绍了Lua中的string库(字符串函数库)总结,本文讲解了string库 ...
- Python系列之模块、和字符串格式化
Python 模块 模块让你能够有逻辑地组织你的Python代码段. 把相关的代码分配到一个 模块里能让你的代码更好用,更易懂. 模块也是Python对象,具有随机的名字属性用来绑定或引用. 模块分为 ...
- sscanf的字符串格式化用法
sscanf()为C语言标准库函数,用于从指定字符串中读入与指定格式相符的数据.函数原型声明在stdio.h头文件中: int sscanf(const char *str, const char * ...
- python笔记3-输出输入、字符串格式化
输入.输出 python怎么来接收用户输入呢,使用input函数,python2中使用raw_input,接收的是一个字符串,输出呢,第一个程序已经写的使用print,代码入下: 1 2 name=i ...
- Haskell语言学习笔记(86)字符串格式化与插值
String 的格式化 Text.Printf 这个模块用来处理字符串格式化. printf :: PrintfType r => String -> r printf 用于格式化字符串, ...
- string.Format对C#字符串格式化[转]
string.Format对C#字符串格式化 String.Format 方法的几种定义: String.Format (String, Object) 将指定的 String 中的格式项替换为指定的 ...
随机推荐
- GridView利用PagerTemplate做分页显示设置上一页下一页转到下拉转页
效果如图: 代码如下: aspx页: <asp:GridView ID="GridViewMain" runat="server" OnPageIndex ...
- 推荐几款我一直在用的chrome插件(下)
请先看:推荐几款我一直在用的chrome插件(上) 6. Pocket 可以很方便的保存文章.视频等供以后查看,即实现了“Read it later”功能.有了 Pocket,您可以将所有想下次读的内 ...
- SVN部署和使用
一.SVN介绍 svn(subversion)是近年来崛起的版本管理工具,是cvs的接班人.目前,绝大多数开源软件都使用svn作为代码版本管理软件. 二.服务器端和客户端 1.服务器端软件Subver ...
- EBS提交请求出现REP-3000错误
在AIX上利用并发请求提交报表的時候,出现如下错误:REP-3000: Internal error starting Oracle Toolkit.这是因为Report Server需要X-Wind ...
- Linux 下安装JRuby
安装ruby cd git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv ...
- gitlab基本维护和使用
基本介绍 GitLab是一个自托管的Git项目仓库,可以自己搭建个人代码管理的仓库,功能与github类似. 安装 下载 gitlab下载地址: https://about.gitlab.com/do ...
- plsql配置数据库连接
工具/原料 PL/SQL 方法/步骤 在Oracle的安装文件下查找tnsnames.ora文件,一般路径如: ORACLE_HOME%\network\admin下: 如果真的找不到路径 ...
- 疯狂了!当游戏爱上MongoDB会怎么样???
导读 前端时间魔兽这个电影我相信大家都看过了哈,作为一个码农,有时候我也会去思考魔兽世界这个游戏背后他的一些设计和实现,比如他用什么数据库.当然真正用什么数据库这个我是不确定的,我们今天的主题是当游戏 ...
- 耿丹CS16-2班第三次作业汇总
-- Deadline: 2016-10-12 22:48 -- 作业内容: 1.实验2-6 猜数字游戏 2.实验2-7 判断能否为三角形 3.实验2-8 个人所得税计算器 -- 第三次作业总结: 1 ...
- MVC中使用Entity Framework 基于方法的查询学习笔记 (二)
解释,不解释: 紧接上文,我们在Visual Studio2012中看到系统为我们自动创建的视图(View)文件Index.cshtml中,开头有如下这句话: @model IEnumerable&l ...