软件架构设计之Utility模块——string
YKString类是对STL 中的std::wstring的功能扩展,没有什么好解释的了,就直接看代码吧。
头文件:
class YKString : public std::wstring { public: typedef std::wstring::size_type size_type; YKString() : std::wstring() {} YKString(const std::wstring& str, size_type pos = 0, size_type n = npos) : std::wstring(str, pos, n) {} YKString(const value_type* str) : std::wstring(str) {} YKString(const value_type* str, size_type n) : std::wstring(str, n) {} YKString(size_type n, value_type val) : std::wstring(n, val) {} YKString(value_type ch) : std::wstring(1, ch) {} YKString(const std::string& str) { Assign(str.c_str()); } YKString(const YK_CHAR* str) { Assign(str); } template <class InputIter> YKString(InputIter fIter, InputIter lIter) : std::wstring(fIter, lIter) { } ~YKString() {} YKString& operator= (const value_type str) { assign(1, str); return *this; } YKString& operator= (const value_type* str) { assign(str); return *this; } YKString& operator= (const std::wstring& str) { assign(str.c_str()); return *this; } YKString& operator= (const std::string& str) { Assign(str.c_str()); return *this; } YKString& operator= (const YK_CHAR* str) { Assign(str); return *this; } YKString& operator+= (const YKString& str) { return (*this += str.c_str());} YKString& operator+= (const value_type* str) { append(str); return *this; } ////////////////////////////////////////////////////////////////////////// // 非变更操作 // 指定pos的字符是否为小写字母、pos==npos则是否全为小写字母 YK_BOOL IsLower(size_type pos = npos) const; // 指定pos的字符是否为大写字母、pos==npos则是否全为大写字母 YK_BOOL IsUpper(size_type pos = npos) const; // 指定pos的字符是否为数字、pos==npos则是否全为数字 YK_BOOL IsNumeric(size_type pos = npos) const; // 指定pos的字符是否为字母(不分大小写)、pos==npos则是否全为字母(不分大小写) YK_BOOL IsAlpha(size_type pos = npos) const; // 指定pos的字符是否为字母或数字、pos==npos则是否全为字母或数字 YK_BOOL IsAlnum(size_type pos = npos) const; // 指定pos的字符是否为空白字符、pos==npos则是否全为空白字符 YK_BOOL IsBlank(size_type pos = npos) const; // 忽略大小写的比较两个字符串 YK_INT iCompare(const YKString& rhs) const; // know-C++ // 意义是将*this设置为const,即将this指针指向用来调用该成员函数的对象设置为const,那么该成员函数不可以修改这个对象 // const成员函数只能调用const成员函数,不能调用非const成员函数 // const成员函数可以调用成员变量,但是不能修改成员变量 // const成员函数可以修改mutable修饰的成员变量;如果成员变量是指针的话,可以修改指针指向的变量的值 ////////////////////////////////////////////////////////////////////////// // 变更操作 // 将字母全转为小写 YKString& ToLower(); // 将字母全转为大写 YKString& ToUpper(); // 以rVal替换所有lVal字符串 YKString& Replace(const YKString& lVal, const YKString& rVal); // 去除字符串左边的空白字符 void TrimLeft(); // 去除字符串右边的空白字符 void TrimRight(); // 去除字符串左右两边的空白字符 void Trim(); // 字符串追加指定类型的值,precision为double型的精度 template <typename T> void Append(T val, size_type precision = 0) { append(Format(val, precision).c_str()); } ////////////////////////////////////////////////////////////////////////// /// 查找 // 为find_first_of的忽略大小写版本 size_type ifind_first_of(const YKString& str, size_type off = 0, size_type count = 0); // 为find_first_not_of的忽略大小写版本 size_type ifind_first_not_of(); // 为find_last_of的忽略大小写版本 size_type ifind_last_of(); // 为find_last_not_of的忽略大小写版本 size_type ifind_last_not_of(); // size_type find_nth(); size_type ifind_nth(); YKString find_head(const YKString& sep) const; YKString find_tail(const YKString& sep) const; ////////////////////////////////////////////////////////////////////////// // 高级操作 // 转换为string std::string ToString() const; // 将容器内的内容以sep字符串作为分隔符拼接 // bPair = false,格式形如:XXXwstrSepXXX // bPari = true,格式形如:XXXwstrSepXXXwstrSep template <typename T> static YKString Join(const T& container, const YKString& sep, YK_BOOL bPair = false) { T::const_iterator fIter = container.begin(); T::const_iterator lIter = container.end(); return Join(fIter, lIter, sep, bPair); } // 将迭代器内的内容以sep字符串作为分隔符拼接 // bPair = false,格式形如:XXXwstrSepXXX // bPari = true,格式形如:XXXwstrSepXXXwstrSep template <typename InputIter> static YKString Join(InputIter fIter, InputIter lIter, const YKString& sep, YK_BOOL bPair = false) { YKString strRt; for (; fIter != lIter; ++fIter) { strRt.Append(*fIter); strRt.append(sep.c_str()); } if (false == bPair && !strRt.empty()) { strRt.erase(strRt.length() - sep.length()); } return strRt; } // 将以sep分隔的字符串分解到vector容器中 template <typename T> std::vector<T> Parse(const YKString& sep) const { std::vector<T> vecVal; size_type idxPre = 0; size_type idx = find(sep.c_str()); while (idx != YKString::npos) { YKString strTemp = substr(idxPre, idx-idxPre); vecVal.push_back(strTemp.Convert<T>()); idx += sep.size(); idxPre = idx; idx = find(sep, idx); } if (idxPre <= size() - sep.size()) { YKString strTemp = substr(idxPre); vecVal.push_back(strTemp.Convert<T>()); } return vecVal; } // 将值转换为YKString,可指定浮点数的格式化精度 template <typename T> static YKString Format(T val, size_type precision = 0) { std::wostringstream stream; if (precision > 0) { stream.precision(precision); stream.flags(std::wostringstream::fixed); } stream << val; return YKString(stream.str()); } // 数字转为YKString,按宽度格式化,左边填充0 static YKString FormatDigit(YK_LONG val, size_type width); // 将字符串里内容转换为指定的类型 template <typename T> T Convert() const { try { return boost::lexical_cast<T>(c_str()); } catch (boost::bad_lexical_cast&) { if (!empty()) // 字符串内存在不符合指定类型的字符 assert(0); return T(); // 空字符串返回类型的默认值 } } // 将字符串里的RGB转换为整形值,字符串内容形式要求:(RGB(xxx,xxx,xxx)) YK_ULONG ConvertRGB(); private: void Assign(const YK_CHAR* pChar); };
实现文件:
YK_BOOL YKString::IsLower( size_type pos /* = npos */ ) const { if (empty()) return false; if (pos == npos) { for (const_iterator i = begin(); i != end(); ++i) { if (!std::islower(*i, std::locale())) return false; } } else { YKString strTemp = at(pos); return strTemp.IsLower(); } return true; } YK_BOOL YKString::IsUpper( size_type pos /* = npos */ ) const { if (empty()) return false; if (pos == npos) { for (const_iterator i = begin(); i != end(); ++i) { if (!std::isupper(*i, std::locale())) return false; } } else { YKString strTemp = at(pos); return strTemp.IsUpper(); } return true; } YK_BOOL YKString::IsNumeric( size_type pos /* = npos */ ) const { if (empty()) return false; if (pos == npos) { for (const_iterator i = begin(); i != end(); ++i) { if (!std::isdigit(*i, std::locale())) return false; } } else { YKString strTemp = at(pos); return strTemp.IsNumeric(); } return true; } YK_BOOL YKString::IsAlpha( size_type pos /* = npos */ ) const { if (empty()) return false; if (pos == npos) { for (const_iterator i = begin(); i != end(); ++i) { if (!std::isalpha(*i, std::locale())) return false; } } else { YKString strTemp = at(pos); return strTemp.IsAlpha(); } return true; } YK_BOOL YKString::IsAlnum( size_type pos /* = npos */ ) const { if (empty()) return false; if (pos == npos) { for (const_iterator i = begin(); i != end(); ++i) { if (!std::isalnum(*i, std::locale())) return false; } } else { YKString strTemp = at(pos); return strTemp.IsAlnum(); } return true; } YK_BOOL YKString::IsBlank( size_type pos /* = npos */ ) const { if (empty()) return false; if (pos == npos) { for (const_iterator i = begin(); i != end(); ++i) { if (!std::isblank(*i, std::locale())) return false; } } else { YKString strTemp = at(pos); return strTemp.IsBlank(); } return true; } YK_INT YKString::iCompare( const YKString& rhs ) const { const_iterator iter = begin(); const_iterator iterEnd = end(); const_iterator iterRhs = rhs.begin(); const_iterator iterRhsEnd = rhs.end(); while (iter != iterEnd && iterRhs != iterRhsEnd) { value_type c1(std::tolower(*iter, std::locale())); value_type c2(std::tolower(*iterRhs, std::locale())); if (c1 < c2) return -1; else if (c1 > c2) return 1; ++iter; ++iterRhs; } if (iter == iterEnd) return iterRhs == iterRhsEnd ? 0 : -1; return 1; } YKString& YKString::ToLower() { for (iterator i = begin(); i != end(); ++i) { *i = std::tolower(*i, std::locale()); } return *this; } YKString& YKString::ToUpper() { for (iterator i = begin(); i != end(); ++i) { *i = std::toupper(*i, std::locale()); } return *this; } YKString& YKString::Replace( const YKString& lVal, const YKString& rVal ) { size_type lastpos = 0, thispos; while ((thispos = find(lVal, lastpos)) != npos) { replace(thispos, lVal.size(), rVal); lastpos = thispos + rVal.size(); } return *this; } void YKString::TrimLeft() { const_iterator i = begin(); for (; i != end(); ++i) { if (!std::isspace(*i, std::locale())) break; } erase(begin(), i); } void YKString::TrimRight() { const_reverse_iterator ri = rbegin(); for (; ri != rend(); ++ri) { if (!std::isspace(*ri, std::locale())) break; } erase(rbegin().base(), ri.base()); } void YKString::Trim() { TrimLeft(); TrimRight(); } YKString::size_type YKString::ifind_first_of(const YKString& str, size_type off /* = 0 */, size_type count /* = 0 */) { YKString temp = str; temp.ToLower(); count = count > 0 ? count : temp.length(); return find_first_of(temp.c_str(), off, count); } YKString::size_type YKString::ifind_first_not_of() { return 0; } YKString::size_type YKString::ifind_last_of() { return 0; } YKString::size_type YKString::ifind_last_not_of() { return 0; } YKString::size_type YKString::find_nth() { return 0; } YKString::size_type YKString::ifind_nth() { return 0; } YKString YKString::find_head(const YKString& sep) const { size_type pos = find(sep.c_str()); if (pos != YKString::npos) { return std::move(substr(0, pos)); } return L""; } YKString YKString::find_tail(const YKString& sep) const { size_type pos = find_last_of(sep.c_str()); if (pos != YKString::npos) { return std::move(substr(pos+sep.size())); } return L""; } YKString YKString::FormatDigit( YK_LONG val, size_type width ) { YKBuffer<YK_WCHAR> temp(20); YKString str = L"%0"; str += YKString::Format(width); str += L"d"; swprintf(temp.Begin(), temp.Size(), str.c_str(), val); return temp.Begin(); } YK_ULONG YKString::ConvertRGB() { YK_ULONG rgbVal = 0; size_type fPos = find(L'('); size_type lPos = find(L')'); if (fPos != npos && lPos != npos) { YKString strVal = substr(fPos+1, lPos-fPos-1); std::vector<YK_ULONG> vecVal = strVal.Parse<YK_ULONG>(L","); if (vecVal.size() == 3) { // #ifdef _MSC_VER && _WINDOWS // rgbVal = RGB(vecVal[0], vecVal[1], vecVal[2]); // #endif // _MSC_VER } } return rgbVal; } std::string YKString::ToString() const { size_t size = this->size(); YKBuffer<YK_CHAR> buff(size+1); size_t rtValue = 0; wcstombs_s(&rtValue, buff.Begin(), size+1, c_str(), YK_UINT_MAX); buff[size] = 0; return buff.Begin(); } void YKString::Assign( const YK_CHAR* pChar ) { size_t size = strlen(pChar); YKBuffer<YK_WCHAR> buff(size+1); size_t rtValue = 0; mbstowcs_s(&rtValue, buff.Begin(), size+1, pChar, YK_UINT_MAX); buff[size] = 0x00; assign(buff.Begin()); }