在实际开发过程中,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. 一.ubuntu14.04安装、亮度设置、显卡设置等一体化讲解

    一.ubuntu14.04安装 安装步骤很简单的,相信你只要知道并且决定安装ubuntu,你就不会在安装上有问题,下载网址 http://www.ithome.com/html/soft/81539. ...

  2. jQuery二级联动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 用include()和ob_get_contents( )方法 生成静态文件

    1. 生成静态文件可以在打开缓冲区的前提下,用include()方法去包含要执行的动态文件,这样该动态文件就会在缓冲区中执行,执行完毕后的静态HTML代码就保存在缓冲区中,然后用ob_get_cont ...

  4. python 爬虫时遇到问题及解决

    源代码: #unicoding=utf-8import reimport urllib def gethtml(url): html=urllib.urlopen(url) page=html.rea ...

  5. Swift笔记3

    赋值运算符" = " let (x,y) =(10,45) var str = "luo" + "shaui"    //会得到luoshu ...

  6. 01UITextField基础知识

    文字属性 文字属性包括:text; placeholder(默认使用70%灰色):font:textColor;textAligment. 文字大小 文字大小包括:adjustsFontSizeToF ...

  7. Struts2 注解(转)

    转自:http://blog.csdn.net/wwwqvod/article/details/6214431 也叫Zero Configuration(零配置),它省去了写xml文件的麻烦,可以直接 ...

  8. MYSQLinsert速度过慢

    MYSQLinsert速度过慢最近在用MySQL做存储,测试中发现插入数据太慢了,插入速度只有20 MY SQL insert 速度过慢最近在用MySQL做存储,测试中发现插入数据太慢了,插入速度只有 ...

  9. 复旦大学EWP菁英女性课程(复旦卓越女性课程改版后第一期) _复旦大学、女性课程、高级研修班、心理学、EWP_培训通课程

    复旦大学EWP菁英女性课程(复旦卓越女性课程改版后第一期) _复旦大学.女性课程.高级研修班.心理学.EWP_培训通课程 复旦大学EWP菁英女性课程(复旦卓越女性课程改版后第一期)    学      ...

  10. Hibernate 1、Hello Hibernate

    所使用到的jar 包: 1.创建实体类 public class User { private Integer id; private String name; private String addr ...