zoukankan      html  css  js  c++  java
  • 扩展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("  Hello ExString "));  
    16.     tcout << _T("result of triming left:") << s.trimLeft(_T("  ")) << endl;  
    17.     tcout << _T("result of triming right:") << s.trimRight(_T(" ")) << 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. }  

    输出:

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

  • 相关阅读:
    [debug] 解决在C++编写过程中的“找到一个或多个多重定义的符号”
    调试事件的收集
    [ida]查看某一函数在程序中被谁引用
    IDA+Windbg IDA+OD 连动调试插件
    一个简单的创建被调试进程的案例
    LOAD_DLL_DEBUG_EVENT 时读取 DllName
    【编译系统01】编译器
    [动态规划]石子合并问题
    xBIM 基础15 IFC导出Excel报表
    xBIM 基础14 使用LINQ实现最佳性能(优化查询)
  • 原文地址:https://www.cnblogs.com/findumars/p/5006182.html
Copyright © 2011-2022 走看看