扩展C++ string类

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

头文件:exstring.h

 

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片

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

 

 

使用举例:

 

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片

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

输出:

扩展C++ string类

 

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

原文链接: https://www.cnblogs.com/findumars/p/5006182.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    扩展C++ string类

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/225164

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午12:42
下一篇 2023年2月13日 下午12:42

相关推荐