扩展C++ string类

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

头文件:exstring.h

[cpp] view plaincopy

  1. /*
  2. Author: wuqiang
  3. Email:  [email protected]
  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;

使用举例:

[cpp] view plaincopy

  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

时间: 2024-10-02 20:34:11

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

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

string 类的扩展方法列表(基本相同于 IEnumerable<T> 接口的成员列表): Aggregate<>     //累加 All<>        //是否都满足条件 Any<>        //是否有一个满足条件 AsEnumerable<>  // AsParallel<>    // AsQueryable<>    // Average<>      //平均值 Cast<>

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

本文源码:GitHub·点这里 || GitEE·点这里 一.String类简介 1.基础简介 字符串是一个特殊的数据类型,属于引用类型.String类在Java中使用关键字final修饰,所以这个类是不可以继承扩展和修改它的方法.String类用处极广泛,在对String对象进行初始化时,和基本类型的包装器类型一样,可以不使用new关键字构造对象.(是真的妖娆...) 2.类构造和方法 String类结构 特点:final关键字修饰,实现Serializable序列化接口,Comparable

原生js的String类扩展

文章转自:http://www.cnblogs.com/zfc2201/archive/2012/12/16/2820335.html JS String类拓展方法: 1 //获取字符数组 2 String.prototype.toCharArray = function() { 3 return this.split(""); 4 } 5 //获取N个相同的字符串 6 String.prototype.repeat = function(num) { 7 var tmpArr = [

[Swift]扩展String类:extension String

请参考本博客另一篇技术博文:<[Swift]字符串(String类.NSString类)常用操作> 1 extension String { 2 3 //获取字符串首字符 4 var first: String 5 { 6 get 7 { 8 return String(self[startIndex]) 9 } 10 } 11 12 // 获取字符串最后一个字符 13 var last: String 14 { 15 get 16 { 17 let index = self.index(be

C++string类用法

1.string类的输入操作(string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作) operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名. 这是C++扩展运算符功能的方法.关于operator的更多内容不在这里详细说明 string str1;      cin >> str1;     //当用cin>>进行字符串的输入的时候,遇到空格的

[转]C/C++关于string.h头文件和string类

学习C语言时,用字符串的函数例如stpcpy().strcat().strcmp()等,要包含头文件string.h 学习C++后,C++有字符串的标准类string,string类也有很多方法,用string类时要用到string.h头文件. 我现在看vc的书上也有CString类,这个要包含什么,怎么用? 我现在很迷惑,这两个 string.h有什么区别.是怎么回事 且看一: 这两个一个是标准C库的,定义了一些字符串的处理函数.一个是标准C++库的,定义了标准C++的std::string类

黑马程序员——String类

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- String类 (一). 认识String 字符串是一个特殊的对象,一旦初始化就不可改变. 有两种方式定义一个字符串对象: (1)String str = “abc”; //它在执行时是在字符串常量池中创建一个对象,并把地址赋给引用型变量

Javascript String类的属性及方法

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

[Java] String类, StringBuffer类

1. String 类 1. 创建: String s1 = new String; s1 = "abc"; String s2 = new String("abc"); char c[] = {'a', 'b', 'c'}; String s3 = new String(c); String s4 = "abc"; 1. 常用方法 2.1 int length() 返回字符串的长度 2.2 char charAt(int index) 返回字符