歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 擴展C++ string類

擴展C++ string類

日期:2017/3/1 9:41:23   编辑:Linux編程

在實際開發過程中,C++string類使用起來有很多不方便的地方,筆者根據根據這些不足簡單的擴展了這個類,如增加與數字之間的相互轉化和格式化字符串。不足的地方望指正。讀者也可以根據自己需求繼續擴展。

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

將C語言梳理一下,分布在以下10個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成長之路(十):其他高級議題

    頭文件:exstring.h

/*
Author: wuqiang
Email: [email protected]
Description:exstring is a subclass of basic_string.It is added some userful
operations,such as toUpper,toLower,toNumber,fromNumber,format,etc.It can also
convert between basic_string seamlessly,which is very important for compatibility.
And it is almostly a wrapper of some C++ standard library,so there should be no bugs.
If you find some,please let me known.It is totally free,you can use it in any way you desire.
*/
#pragma once

#include <string>
#include <stdarg.h>
#include <algorithm>
#include <sstream>
#include <iomanip>

using namespace std;

#ifndef INLINE
#define INLINE inline
#endif //INLINE

static ios_base::fmtflags BaseFlag(int base)
{
return (base == 16) ? (ios_base::hex) :
( (base == 8) ? (ios_base::oct) : (ios_base::dec) );
}

template<class _Elem> struct ex_char_traits
{
};

template<> struct ex_char_traits<char>
{
static INLINE int ct_vscprintf(const char* format, va_list argptr )
{
return _vscprintf(format, argptr);
}
static INLINE int ct_vstprintf_s(char* buffer, size_t numberOfElements,
const char* format, va_list argptr)
{
return vsprintf_s(buffer, numberOfElements, format, argptr);
}
};

template<> struct ex_char_traits<wchar_t>
{
static INLINE int ct_vscprintf(const wchar_t* format, va_list argptr )
{
return _vscwprintf(format, argptr);
}
static INLINE int ct_vstprintf_s(wchar_t* buffer, size_t numberOfElements,
const wchar_t* format, va_list argptr)
{
return vswprintf_s(buffer, numberOfElements, format, argptr);
}
};

template<class _Elem, class _Traits, class _Ax, class Type>
Type ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
Type t, int base)
{
ss.setf(BaseFlag(base), ios_base::basefield);
ss >> t;
return t;
}

template<class _Elem, class _Traits, class _Ax>
float ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
float t, int/*ignore base*/)
{
ss >> t;
return t;
}

template<class _Elem, class _Traits, class _Ax>
double ConvertToNumber(basic_stringstream<_Elem, _Traits, _Ax>& ss,
double t, int/*ignore base*/)
{
ss >> t;
return t;
}

template<class _Elem, class _Traits, class _Ax, class _ExTraits>
class basic_exstring : public basic_string<_Elem, _Traits, _Ax>
{
public:
typedef basic_exstring<_Elem, _Traits, _Ax, _ExTraits> _Myt;
typedef basic_string<_Elem, _Traits, _Ax> _Mybase;

#pragma region "constructor"

//所有構造函數的行為同basic_string

explicit INLINE _Myt(const _Ax& al = _Ax())
:_Mybase(al)
{
}
INLINE _Myt(const _Myt& rhs)
:_Mybase(rhs)
{
}
INLINE _Myt(const _Myt& rhs, size_type pos, size_type n,const _Ax& al = _Ax())
:_Mybase(rhs, pos, n, al)
{
}
INLINE _Myt(const _Elem *s, size_type n, const _Ax& al = _Ax())
:_Mybase(s, n, al)
{
}
INLINE _Myt(const _Elem *s, const _Ax& al = _Ax())
:_Mybase(s, al)
{
}
INLINE _Myt(size_type n, _Elem c, const _Ax& al = _Ax())
:_Mybase(n, c, al)
{
}
INLINE _Myt(const_iterator first, const_iterator last,const _Ax& al = _Ax())
:_Mybase(first, last, al)
{
}

//string(wstring)轉化為exstring(exwstring)
INLINE _Myt(const _Mybase& base)
:_Mybase(base)
{

}
#pragma endregion //constructor


#pragma region "general operation"

//所有字符轉為大寫,改變自身
_Myt& toUpper()
{
transform(begin(), end(), begin(), toupper);
return *this;
}

//所有字符轉為大寫,不改變自身
_Myt toUpper() const
{
_Myt s;
transform(begin(), end(), s.begin(), toupper);
return s;
}

//所有字符轉為小寫,改變自身
_Myt& toLower()
{
transform(begin(), end(), begin(), tolower);
return *this;
}

//所有字符轉為大寫,不改變自身
_Myt toLower() const
{
_Myt s(_Mysize, _Elem());
transform(begin(), end(), s.begin(), tolower);
return s;
}

//將所有oldStr替換為newStr
_Myt& replace(const _Myt& oldStr, const _Myt& newStr)
{
if (oldStr.empty())
return *this;
size_type index;
while ( (index = find(oldStr)) != npos )
_Mybase::replace(index, oldStr.size(), newStr);
return *this;
}

//刪除左邊所有包含在target中的字符
_Myt& trimLeft(const _Myt& target)
{
while (!empty() && (target.find(*begin()) != npos))
erase(begin());
return *this;
}

//刪除右邊所有包含在target中的字符
_Myt& trimRight(const _Myt& target)
{
while (!empty() && target.find(*rbegin()) != npos)
erase(--end());
return *this;
}

//返回左邊count個字符,count大於總長度則返回整個字符串
_Myt left(size_type count) const
{
return substr( 0, count );
}

//返回右邊count個字符,count大於總長度則返回整個字符串
_Myt right(size_type count) const
{
return substr( _Mysize < count ? 0 : _Mysize - count );
}

//忽略大小寫判斷兩個字符串是否相等
int compareNoCase(const _Myt& rhs) const
{
return toLower().compare(rhs.toLower());
}

//判斷字符串是否以制定字符串開頭
bool beginWith(const _Myt& rhs) const
{
return find(rhs) == size_type(0);
}

//判斷字符串是否以制定字符串結尾
bool endWith(const _Myt& rhs) const
{
if(rhs.size() > _Mysize)
return false;
return compare(_Mysize - rhs.size(), rhs.size(), rhs) == 0;
}
#pragma endregion //general operation


#pragma region "convert between numbers"

//將字符串轉為數字
//base:進制數。可以為8,10,16,如果其它值則強制為10。浮點數則忽略此參數
template<typename T>
T toNumber (int base = 10) const
{
T t = T();
basic_stringstream<_Elem, _Traits, _Ax> ss(_Myptr());
return ConvertToNumber<_Elem, _Traits, _Ax>(ss, t, base);
}

//將整數轉化為字符串
//base:進制數。可以為8,10,16,如果其它值則強制為10
template<typename T>
static _Myt fromNumber ( T number, int base = 10 )
{
basic_stringstream<_Elem, _Traits, _Ax> ss;
ss.setf(BaseFlag(base), ios_base::basefield);
ss << number;
return ss.str();
}

//將float轉化為字符串
//f:格式化參數。可以為'f','e','E','g','G'。'f'為定點數,'e'或'E'表示科學計數法
// 'g'或‘G’表示格式化為定點數或科學計數法,看哪一個表示方便。
//prec:小數點後的位數(定點數表示法)或總的有效位數(科學計數法)
static _Myt fromNumber ( float number, _Elem f = _Elem('g'), int prec = 6 )
{
return fromNumber(static_cast<double>(number), f, prec);
}

//將double轉化為字符串,參數解釋同上
static _Myt fromNumber ( double number, _Elem f = _Elem('g'), int prec = 6 )
{
basic_stringstream<_Elem, _Traits, _Ax> ss;
ss << setprecision(prec);
if ( _Traits::eq(f, _Elem('f')) )
ss << setiosflags(ios_base::fixed);
else if ( _Traits::eq(f, _Elem('e')) || _Traits::eq(f, _Elem('E')) )
ss << setiosflags(ios_base::scientific);
ss << number;
return ss.str();
}
#pragma endregion //convert between numbers


#pragma region "format string"

//將szFormat格式化為字符串,參數解釋同sprintf
void format(const _Elem* szFormat, ...)
{
if(!szFormat)
return;
va_list argList;
va_start(argList, szFormat);
formatV(szFormat, argList);
va_end(argList);
}

//將szFormat格式化為字符串,參數解釋同sprintf
void formatV(const _Elem* szFormat, va_list argList)
{
if(!szFormat)
return;
int nLength = _ExTraits::ct_vscprintf(szFormat, argList);
if(nLength < 0)
return;
resize(nLength);
_ExTraits::ct_vstprintf_s(_Myptr(), nLength + 1, szFormat, argList);
va_end(argList);
}
#pragma endregion //format string
};

typedef basic_exstring<char, char_traits<char>,
allocator<char>, ex_char_traits<char> > exstring;

typedef basic_exstring<wchar_t, char_traits<wchar_t>,
allocator<wchar_t>, ex_char_traits<wchar_t> > exwstring;

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-08/105033p2.htm

Copyright © Linux教程網 All Rights Reserved