在实际开发过程中,C++string类使用起来有很多不方便的地方,笔者根据根据这些不足简单的扩展了这个类,如增加与数字之间的相互转化和格式化字符串。不足的地方望指正。读者也可以根据自己需求继续扩展。

头文件:exstring.h

  1. /*
  2. Author: wuqiang
  3. Email:  debugroot@126.com
  4. Description:exstring is a subclass of basic_string.It is added some userful
  5. operations,such as toUpper,toLower,toNumber,fromNumber,format,etc.It can also
  6. convert between basic_string seamlessly,which is very important for compatibility.
  7. And it is almostly a wrapper of some C++ standard library,so there should be no bugs.
  8. If you find some,please let me known.It is totally free,you can use it in any way you desire.
  9. */
  10. #pragma once
  11. #include <string>
  12. #include <stdarg.h>
  13. #include <algorithm>
  14. #include <sstream>
  15. #include <iomanip>
  16. using namespace std;
  17. #ifndef INLINE
  18. #define INLINE inline
  19. #endif //INLINE
  20. static ios_base::fmtflags BaseFlag(int base)
  21. {
  22. return (base == 16) ? (ios_base::hex) :
  23. ( (base == 8) ? (ios_base::oct) : (ios_base::dec) );
  24. }
  25. template<class _Elem> struct ex_char_traits
  26. {
  27. };
  28. template<> struct ex_char_traits<char>
  29. {
  30. static INLINE int ct_vscprintf(const char* format, va_list argptr )
  31. {
  32. return _vscprintf(format, argptr);
  33. }
  34. static INLINE int ct_vstprintf_s(char* buffer, size_t numberOfElements,
  35. const char* format,  va_list argptr)
  36. {
  37. return vsprintf_s(buffer, numberOfElements, format, argptr);
  38. }
  39. };
  40. template<> struct ex_char_traits<wchar_t>
  41. {
  42. static INLINE int ct_vscprintf(const wchar_t* format, va_list argptr )
  43. {
  44. return _vscwprintf(format, argptr);
  45. }
  46. static INLINE int ct_vstprintf_s(wchar_t* buffer, size_t numberOfElements,
  47. const wchar_t* format,  va_list argptr)
  48. {
  49. return vswprintf_s(buffer, numberOfElements, format, argptr);
  50. }
  51. };
  52. template<class _Elem, class _Traits, class _Ax, class Type>
  53. Type ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
  54. Type t, int base)
  55. {
  56. ss.setf(BaseFlag(base), ios_base::basefield);
  57. ss >> t;
  58. return t;
  59. }
  60. template<class _Elem, class _Traits, class _Ax>
  61. float ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
  62. float t, int/*ignore base*/)
  63. {
  64. ss >> t;
  65. return t;
  66. }
  67. template<class _Elem, class _Traits, class _Ax>
  68. double ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
  69. double t, int/*ignore base*/)
  70. {
  71. ss >> t;
  72. return t;
  73. }
  74. template<class _Elem, class _Traits, class _Ax, class _ExTraits>
  75. class basic_exstring : public basic_string<_Elem, _Traits, _Ax>
  76. {
  77. public:
  78. typedef basic_exstring<_Elem, _Traits, _Ax, _ExTraits> _Myt;
  79. typedef basic_string<_Elem, _Traits, _Ax> _Mybase;
  80. #pragma region "constructor"
  81. //所有构造函数的行为同basic_string
  82. explicit INLINE _Myt(const _Ax& al = _Ax())
  83. :_Mybase(al)
  84. {
  85. }
  86. INLINE _Myt(const _Myt& rhs)
  87. :_Mybase(rhs)
  88. {
  89. }
  90. INLINE _Myt(const _Myt& rhs, size_type pos, size_type n,const _Ax& al = _Ax())
  91. :_Mybase(rhs, pos, n, al)
  92. {
  93. }
  94. INLINE _Myt(const _Elem *s, size_type n, const _Ax& al = _Ax())
  95. :_Mybase(s, n, al)
  96. {
  97. }
  98. INLINE _Myt(const _Elem *s, const _Ax& al = _Ax())
  99. :_Mybase(s, al)
  100. {
  101. }
  102. INLINE _Myt(size_type n, _Elem c, const _Ax& al = _Ax())
  103. :_Mybase(n, c, al)
  104. {
  105. }
  106. INLINE _Myt(const_iterator first, const_iterator last,const _Ax& al = _Ax())
  107. :_Mybase(first, last, al)
  108. {
  109. }
  110. //string(wstring)转化为exstring(exwstring)
  111. INLINE _Myt(const _Mybase& base)
  112. :_Mybase(base)
  113. {
  114. }
  115. #pragma endregion //constructor
  116. #pragma region "general operation"
  117. //所有字符转为大写,改变自身
  118. _Myt& toUpper()
  119. {
  120. transform(begin(), end(), begin(), toupper);
  121. return *this;
  122. }
  123. //所有字符转为大写,不改变自身
  124. _Myt toUpper() const
  125. {
  126. _Myt s;
  127. transform(begin(), end(), s.begin(), toupper);
  128. return s;
  129. }
  130. //所有字符转为小写,改变自身
  131. _Myt& toLower()
  132. {
  133. transform(begin(), end(), begin(), tolower);
  134. return *this;
  135. }
  136. //所有字符转为大写,不改变自身
  137. _Myt toLower() const
  138. {
  139. _Myt s(_Mysize, _Elem());
  140. transform(begin(), end(), s.begin(), tolower);
  141. return s;
  142. }
  143. //将所有oldStr替换为newStr
  144. _Myt& replace(const _Myt& oldStr, const _Myt& newStr)
  145. {
  146. if (oldStr.empty())
  147. return *this;
  148. size_type index;
  149. while ( (index = find(oldStr)) != npos )
  150. _Mybase::replace(index, oldStr.size(), newStr);
  151. return *this;
  152. }
  153. //删除左边所有包含在target中的字符
  154. _Myt& trimLeft(const _Myt& target)
  155. {
  156. while (!empty() && (target.find(*begin()) != npos))
  157. erase(begin());
  158. return *this;
  159. }
  160. //删除右边所有包含在target中的字符
  161. _Myt& trimRight(const _Myt& target)
  162. {
  163. while (!empty() && target.find(*rbegin()) != npos)
  164. erase(--end());
  165. return *this;
  166. }
  167. //返回左边count个字符,count大于总长度则返回整个字符串
  168. _Myt left(size_type count) const
  169. {
  170. return substr( 0, count );
  171. }
  172. //返回右边count个字符,count大于总长度则返回整个字符串
  173. _Myt right(size_type count) const
  174. {
  175. return substr( _Mysize < count ? 0 : _Mysize - count );
  176. }
  177. //忽略大小写判断两个字符串是否相等
  178. int compareNoCase(const _Myt& rhs) const
  179. {
  180. return toLower().compare(rhs.toLower());
  181. }
  182. //判断字符串是否以制定字符串开头
  183. bool beginWith(const _Myt& rhs) const
  184. {
  185. return find(rhs) == size_type(0);
  186. }
  187. //判断字符串是否以制定字符串结尾
  188. bool endWith(const _Myt& rhs) const
  189. {
  190. if(rhs.size() > _Mysize)
  191. return false;
  192. return compare(_Mysize - rhs.size(), rhs.size(), rhs) == 0;
  193. }
  194. #pragma endregion //general operation
  195. #pragma region "convert between numbers"
  196. //将字符串转为数字
  197. //base:进制数。可以为8,10,16,如果其它值则强制为10。浮点数则忽略此参数
  198. template<typename T>
  199. T toNumber (int base = 10) const
  200. {
  201. T t = T();
  202. basic_stringstream<_Elem, _Traits, _Ax> ss(_Myptr());
  203. return ConvertToNumber<_Elem, _Traits, _Ax>(ss, t, base);
  204. }
  205. //将整数转化为字符串
  206. //base:进制数。可以为8,10,16,如果其它值则强制为10
  207. template<typename T>
  208. static _Myt fromNumber ( T number, int base = 10 )
  209. {
  210. basic_stringstream<_Elem, _Traits, _Ax> ss;
  211. ss.setf(BaseFlag(base), ios_base::basefield);
  212. ss << number;
  213. return ss.str();
  214. }
  215. //将float转化为字符串
  216. //f:格式化参数。可以为'f','e','E','g','G'。'f'为定点数,'e'或'E'表示科学计数法
  217. //  'g'或‘G’表示格式化为定点数或科学计数法,看哪一个表示方便。
  218. //prec:小数点后的位数(定点数表示法)或总的有效位数(科学计数法)
  219. static _Myt fromNumber ( float number, _Elem f = _Elem('g'), int prec = 6 )
  220. {
  221. return fromNumber(static_cast<double>(number), f, prec);
  222. }
  223. //将double转化为字符串,参数解释同上
  224. static _Myt fromNumber ( double number, _Elem f = _Elem('g'), int prec = 6 )
  225. {
  226. basic_stringstream<_Elem, _Traits, _Ax> ss;
  227. ss << setprecision(prec);
  228. if ( _Traits::eq(f, _Elem('f')) )
  229. ss << setiosflags(ios_base::fixed);
  230. else if ( _Traits::eq(f, _Elem('e')) || _Traits::eq(f, _Elem('E')) )
  231. ss << setiosflags(ios_base::scientific);
  232. ss << number;
  233. return ss.str();
  234. }
  235. #pragma endregion //convert between numbers
  236. #pragma region "format string"
  237. //将szFormat格式化为字符串,参数解释同sprintf
  238. void format(const _Elem* szFormat, ...)
  239. {
  240. if(!szFormat)
  241. return;
  242. va_list argList;
  243. va_start(argList, szFormat);
  244. formatV(szFormat, argList);
  245. va_end(argList);
  246. }
  247. //将szFormat格式化为字符串,参数解释同sprintf
  248. void formatV(const _Elem* szFormat, va_list argList)
  249. {
  250. if(!szFormat)
  251. return;
  252. int nLength = _ExTraits::ct_vscprintf(szFormat, argList);
  253. if(nLength < 0)
  254. return;
  255. resize(nLength);
  256. _ExTraits::ct_vstprintf_s(_Myptr(), nLength + 1, szFormat, argList);
  257. va_end(argList);
  258. }
  259. #pragma endregion //format string
  260. };
  261. typedef basic_exstring<char, char_traits<char>,
  262. allocator<char>, ex_char_traits<char> > exstring;
  263. typedef basic_exstring<wchar_t, char_traits<wchar_t>,
  264. allocator<wchar_t>, ex_char_traits<wchar_t> > exwstring;

使用举例:

  1. #include <iostream>
  2. #include <tchar.h>
  3. #include "exstring.h"
  4. #ifdef _UNICODE
  5. typedef exwstring tstring;
  6. #define tcout wcout
  7. #else
  8. typedef exstring tstring;
  9. #define tcout cout
  10. #endif //_UNICODE
  11. int main(int argc, char* argv[])
  12. {
  13. tstring s(_T("\t Hello ExString\r\n"));
  14. tcout << _T("result of triming left:") << s.trimLeft(_T("\t ")) << endl;
  15. tcout << _T("result of triming right:") << s.trimRight(_T("\r\n")) << endl;
  16. tcout << _T("result of compare") << s.compareNoCase(_T("hello exstring")) << endl;
  17. tcout << _T("result of converting to upper:") << s.toUpper() << endl;
  18. tcout << _T("result of converting to lower:") << s.toLower() << endl;
  19. tcout << _T("the left 5 chars:") << s.left(5) << endl;
  20. tcout << _T("the right 8 chars:") << s.right(8) << endl;
  21. tcout << _T("result of appending:") << s.append(_T(",exstring is practical")) << endl;
  22. tcout << _T("result of replacing:") << s.replace(_T("exstring"), _T("Exstring")) << endl;
  23. s.format(_T("sizeof(%s) is %d(0x%x)"), _T("exstring"), sizeof(exstring), sizeof(exstring));
  24. tcout << _T("result of formating:") << s << endl;
  25. tcout << tstring(_T("0xFF")).toNumber<int>(16) << endl;
  26. tcout << tstring(_T("-1")).toNumber<unsigned __int64>() << endl;
  27. tcout << tstring(_T("12.3456789")).toNumber<float>() << endl;
  28. tcout << tstring::fromNumber(255) << endl;
  29. tcout << _T("0x") << tstring::fromNumber(__int64(-1), 16).toUpper() << endl;
  30. tcout << tstring::fromNumber(12.3456789, _T('f'), 4) << endl;
  31. tcout << tstring::fromNumber(12.3456789, _T('E'), 4) << endl;
  32. return 0;
  33. }

输出:

http://blog.csdn.net/passion_wu128/article/details/38354541

扩展C++ string类的更多相关文章

  1. ASP.Net string 类的扩展方法 [转]

    string 类的扩展方法列表(基本相同于 IEnumerable<T> 接口的成员列表): Aggregate<>     //累加 All<>        / ...

  2. Java基础篇(02):特殊的String类,和相关扩展API

    本文源码:GitHub·点这里 || GitEE·点这里 一.String类简介 1.基础简介 字符串是一个特殊的数据类型,属于引用类型.String类在Java中使用关键字final修饰,所以这个类 ...

  3. 原生js的String类扩展

    文章转自:http://www.cnblogs.com/zfc2201/archive/2012/12/16/2820335.html JS String类拓展方法: //获取字符数组 String. ...

  4. [Swift]扩展String类:extension String

    请参考本博客另一篇技术博文: <[Swift]字符串(String类.NSString类)常用操作> extension String { //获取字符串首字符 var first: St ...

  5. 电话号码 马赛克*号 string类扩展

    /// <summary> /// 字符串马赛克 /// </summary> /// <param name="source"></pa ...

  6. [Swift]扩展String类:实现find()查找子字符串在父字符串中的位置

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  7. C/C++关于string.h头文件和string类

    学习C语言时,用字符串的函数例如stpcpy().strcat().strcmp()等,要包含头文件string.h 学习C++后,C++有字符串的标准类string,string类也有很多方法,用s ...

  8. C#部分---arraylist集合、arraylist集合中的object数据转换成int类string类等;间隔时间的表示方法;

    ArrayList和Array的区别: 相同点:1.两者都实现了IList.ICollection.IEnumerable接口:       2.两者都可以使用证书索引访问集合中的元素,包括读取和赋值 ...

  9. Javascript String类的属性及方法

    String 类 Attribute and method anchor()              创建一个<a>标签的实例,将其name属性设置为被传递给此方法的字符串 big()  ...

随机推荐

  1. 关于ASP.Net的一些概念 转载

    ①理解 .NET Platform Standard 作者:田园里的蟋蟀 http://www.cnblogs.com/xishuai/archive/2016/05/24/understand-do ...

  2. LED发光二极管

    半导体发光器件包括半导体发光二极管(简称LED).数码管.符号管.米字管及点阵式显示屏(简称矩阵管)等.事实上,数码管.符号管.米字管及矩阵管中的每个发光单元都是一个发光二极管. 一. 半导体发光二极 ...

  3. 【Python】iiblogs ——命令行下的网页收藏夹

    昨天和集训队的几位大大聊天,聊着聊着就聊到了博客的问题,发现几个人要么在CSDN 要么在博客园上, 要记住他们的所有的地址还真是不便,于是灵机一动,何不自己写一款小工具来存储打开他们的博客呢?于是将这 ...

  4. linux下主要是VirtualBox及GuestAdditions的安装

    Linux版本的VirtualBox下载:http://www.virtualbox.org/wiki/Linux_Downloads.请下载对应的版本. RedHat.RHEL:rpm -i vh ...

  5. POJ3322-经典的游戏搜索问题

    临近毕业真是各种琐事多,好不容易写完几万字蛋疼的论文,又接着户口档案挂靠,毕业旅游,20多个离校盖章,签证被check了几个星期还没消息,希望8月初能走啊. 各种事情之下,人就是懒加心散,好久没写代码 ...

  6. android listview 三种适配器设置

    1: public class ArrayAdapterActivity extends ListActivity { @Override public void onCreate(Bundle sa ...

  7. SharePoint 2013 讨论板列表"Connect to Outlook" 不可用解决方案

    本文讲述 SharePoint 2013 讨论板列表"Connect to Outlook" 不可用解决方案. SharePoint中的讨论板列表是可以集成到Outlook里面去的 ...

  8. Unity大中华区主办 第二届Unity 游戏及应用大赛 实力派精品手游盘点

    Unity是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎.包含如今时 ...

  9. Java面试题之数据库三范式是什么

    为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某一种设计要求的总结.要想设计一个结构合理的关系型数据库,必须满足一定的范式. 在实际 ...

  10. 温故而知新之数据库的分离和附加…高手请跳过….

    sql server2005分离数据库后,把路径下的两个文件拷到自己想要存放的目录下,然后再附加