C++ 寫的_string類,兼容std::string, MFC CString和 C# 的string

代碼例子:

using namespace lf;

int main()
{
?? ? ?
?? ?CString s1 = _t("http://www.csdn.net");

?? ?_string s2 = s1;

?? ?CString s3 = s2;

?? ?_pcn(s1);

?? ?_pcn(s2);

?? ?_pcn(s3);

?? ?return 0;
}

輸出:

_Str.h

/*******************************************************************************************
文件名						: _Str<T>.h功能							: 模擬std::string C# _Str<T> Java._Str<T>程序字體						: Consolas,11作者							: 李鋒手機							: 13828778863Email						: ruizhilf@139.com創建時間						: 2016年07月06日------------------------------最后一次修改時間:2024年04月25日
***********************************************************************************************/#ifndef __STR_H_
#define __STR_H_#include "global_c_str.h"
#include "_Memory.h"
#include "_Math.h"//#define _STR_DEBUG_#ifndef _CLR_#elseusing namespace System;
#endif_LF_BEGIN_template<class T1, class T2>
class _Pair;template<class T>
class _Array;template<class T>
class _iterator;template<class T>
class _reverse_iterator;/*
template<class T>
class charIterator
{
private:T* _pChar;
public:/// <summary>/// 構造函數,傳值迭代器管理的值/// </summary>/// <param name="pNode"></param>inline charIterator(T* pChar) { _pChar = pChar; }/// <summary>/// 比較實現/// </summary>/// <param name="that"></param>/// <returns></returns>bool operator != (const charIterator& that) { return _pChar != that._pChar; }/// <summary>/// 自增實現/// </summary>/// <returns></returns>inline charIterator& operator ++ () { ++_pChar;	return *this; }/// <summary>/// 解引用,取值/// </summary>/// <returns></returns>inline T& operator * () { return *_pChar; }//LDIterator(const LDIterator&) = delete;//LDIterator& operator=(const LDIterator&) = delete;//~LDIterator() = default;
};
*//// <summary>
///  字符串類
/// </summary>
/// <typeparam name="T"></typeparam>
/// 創建時間: ????-??-??     最后一次修改時間:2022-11-13
template<typename T>
class _Str  //不要繼承任何類
{
protected:T*			_pData;						//指針,指向第一個元素int			_nLength;					//無素個數int         _nBuffer;					//剩余緩沖區大小int         _nDefaultBuffer = 8;		//每次分配內容多分配缺省緩沖區大小int         _nAutoBufferCount = 0;      //自動設置緩沖次數的計數器public:static const int npos = -1;public://-----------------------------------------------------------------------------屬性/// <summary>/// 返回以零為結尾的字符串指針,相當于 c_str()/// </summary>/// <returns></returns>inline const T* GetData() const { return _pData; }/// <summary>/// 返回以零為結尾的字符串指針,相當于 c_str()/// </summary>__declspec(property(get = GetData)) const T* Data;/// <summary>/// 字符串長度/// </summary>/// <returns></returns>inline const int GetLength() const { return _nLength; }/// <summary>/// 字符串長度/// </summary>__declspec(property(get = GetLength)) const int Length;/// <summary>/// 返回內存使用的長度,以 Byte 計數。/// </summary>/// <returns></returns>inline const int GetMemoryLength()const { return sizeof(T) * (_nLength + _nBuffer + 1); }/// <summary>/// 返回內存使用的長度,以 Byte 計數。/// </summary>/// <returns></returns>__declspec(property(get = GetMemoryLength)) const int MemoryLength;/// <summary>/// 返回字符串所占用的內存,以 Byte 計數。/// </summary>/// <returns></returns>inline const int GetDataMemoryLength()const { return sizeof(T) * (_nLength); }/// <summary>/// 返回字符串所占用的內存,以 Byte 計數。。/// </summary>/// <returns></returns>__declspec(property(get = GetDataMemoryLength)) const int DataMemoryLength;/// <summary>/// 獲取默認緩沖數量/// </summary>/// <returns></returns>inline int GetDefaultBuffer() const { return _nDefaultBuffer; }/// <summary>/// 設置默認緩沖數量/// </summary>/// <param name="nDefaultBuffer"></param>inline void SetDefaultBuffer(const int& nDefaultBuffer) { _nDefaultBuffer = nDefaultBuffer; }/// <summary>/// 獲取默認緩沖數量/// </summary>__declspec(property(get = GetDefaultBuffer, put = SetDefaultBuffer)) const int DefaultBuffer;/// <summary>/// 獲取當前緩沖數量/// </summary>/// <returns></returns>inline int GetBuffer() const { return _nBuffer; }/// <summary>/// 獲取當前緩沖數量/// </summary>__declspec(property(get = GetBuffer)) const int Buffer;/// <summary>/// 是否為空/// </summary>/// <returns></returns>inline bool IsEmpty() { return _nLength == 0; }/// <summary>/// 返回自動設置的緩沖次數/// </summary>/// <returns></returns>inline int GetAutoBufferCount()const { return _nAutoBufferCount; }public://---------------------------------------------------------------------------------構造與析構/// <summary>/// 缺省構造,默認為15個字符的緩沖大小/// </summary>inline _Str<T>(){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>()\n");
#endif  InitData(_nDefaultBuffer);}inline explicit _Str<T>(const int& nBuffer){InitData(nBuffer);}inline explicit _Str<T>(const T& ch){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>::_Str<T>(const T& ch);\n");
#endif  InitData(1);_pData[0] = ch;_pData[1] = 0;_nBuffer = 0;_nLength = 1;}/// <summary>/// std::string result(maxLen + 1, '0');/// </summary>/// <param name="nLength"></param>/// <param name="ch"></param>/// 創建時間: 2024-04-21      最后一次修改時間:2024-04-21inline explicit _Str<T>(const size_t& nLength, const T& ch){InitData(nLength,ch,true);			}inline _Str<T>(const _Str<T>& rhs){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>(const _Str<T>& rhs)\n");
#endif //  _STR_DEBUG_if (rhs._nLength == 0)InitData(0);else{InitData(rhs._nLength);Add(rhs._pData, rhs._nLength);}}/// <summary>///  拷貝構造,默認為0個字符的缺省緩沖/// </summary>/// <param name="pStr"></param>/// <param name="nBuffer">緩沖區個數</param>/// <param name="bZeroBuffer">是否實始化 buffer</param>/// 創建時間: ????-??-??      最后一次修改時間:2023-02-08inline _Str<T>(const T* pStr, const int& nBuffer = 0, bool bZeroBuffer = false){// 定義: int _Str<T>::CSharp_IndexOf(const _Str<T>& sSub) const// _Str<T> s = L"abc";// s.CSharp_IndexOf( null ); 此時編譯時會把 null 轉換為 _Str<T>,用的就是這個構造涵數。 
#ifdef  _STR_DEBUG_//_cout << _t("調用函數:_Str<T>::_Str<T>(const T *pStr,const int nBuffer)\t 參數為:") << _getc(pStr) << _geti(nBuffer) << _t("\n");#endif //錯不能用這個,當_Str<T> aStr = null 時,先調用_Str<T>::StrLen_t<T>(pStr)//_Str<T>::_Str<T>(const T *pStr) : _Array<T>(pStr,_Str<T>::StrLen_t<T>(pStr))//并且構造函數中的子類虛函數是無效的,例如:當構造_Array時,_Str<T>還未構造出來int nTrueBuffer = nBuffer >= 0 ? nBuffer : 0;if (pStr != null){int nLength = _Math::strLen_t<T>(pStr);InitData(nLength + nTrueBuffer);this->Add(pStr, nLength);}else{InitData(nTrueBuffer);}if (bZeroBuffer){ZeroBuffer();}}/// <summary>/// 拷貝構造函數/// </summary>/// <param name="pstr">要拷貝的字符串</param>/// <param name="nStrLength">要拷貝的字符串長度</param>/// <param name="nCopyStart">從那里開始拷貝,索引從零開始</param>/// <param name="nCopyLength">要拷貝的長度</param>/// <param name="nBuffer">字符串區緩沖區長度</param>/// 創建時間: ????-??-??      最后一次修改時間:2021-11-02inline explicit _Str<T>(const T* pstr, const int& nStrLength, const int& nCopyStart, const int& nCopyLength, const int& nBuffer = 0){#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>(const T* pstr, const int& nStrLength, const int& nCopyStart, const int& nCopyLength, const int& nBuffer)\n");#endif if (pstr == null || nCopyLength == 0 || nCopyStart >= nStrLength){InitData(nBuffer);return;}if (nCopyLength + nCopyStart <= nStrLength){_nLength = nCopyLength;}else{_nLength = nStrLength - nCopyStart;}_nDefaultBuffer = 0;_nBuffer = nBuffer;_pData = _Memory::New<T>(_nLength + _nBuffer + 1);_Memory::Copy(_pData, pstr + nCopyStart, _nLength);_pData[_nLength] = 0;}inline _Str<T>(const _stdstr& sText){InitData(sText.length() + _nDefaultBuffer);Add(sText.c_str(), sText.length());}#if _CLR_/**inline _Str<T>(String^ sText){if (sText->Length > 0){int nLength = sText->Length;InitData(nLength + _nDefaultBuffer);for (int i = 0; i < nLength; ++i) {_pData[i] = sText[i];}_nLength = nLength;_nBuffer -= nLength;_pData[nLength] = 0;}else{InitData(_nDefaultBuffer);}}*//// <summary>/// /// </summary>/// <param name="sText"></param>/// <param name="nBuffer"></param>/// <param name="bZeroBuffer"></param>/// 創建時間: ????-??-??      最后一次修改時間:2022-02-08inline _Str<T>(String^ sText, const int& nBuffer = 0, bool bZeroBuffer = false){if (nBuffer >= 0)InitData(sText->Length + nBuffer);elseInitData(sText->Length);//拷貝sTextif (sText->Length > 0){int nLength = sText->Length;for (int i = 0; i < nLength; ++i) {_pData[i] = sText[i];}_nLength = nLength;_nBuffer -= nLength;_pData[nLength] = 0;}if (bZeroBuffer){ZeroBuffer();}}inline  operator String ^ () const { return gcnew String(_pData); }#endifT* First()const { return _pData; }T* last()const { return _pData + _nLength - 1; }//inline charIterator begin()const { return charIterator(_pData); }//inline charIterator end()const { return charIterator(_pData + _nLength); }// C++用for遍歷自定義類inline T* begin()const { return _pData; }inline T* end()const { return _pData + _nLength; }inline ~_Str<T>(){
#ifdef _STR_DEBUG__cout << _t("_Str<T>:\t inline ~_Str<T>()\n");
#endifClearMemory();}public://-----------------------------------------------------------------------------運算符重載inline _Str<T>& operator=(const T* pStr){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>& _Str<T>::operator=(const T *pStr)\n");#endif   if (_pData != pStr){Clear();Add(pStr);}return *this;}//重載的下標操作符inline T& operator[](const int& nIndex)const{
#ifdef  _STR_DEBUG_assert(nIndex < _nLength && nIndex >= 0);
#endif   return _pData[nIndex];}//_Str<T> s1,s2;// s1 = s2;        //此時設用這個函數,如果沒寫這個函數,//                       則調用基類_Array<T>& _Array<T>::operator=(const _Array<T> &rhs)inline _Str<T>& operator=(const _Str<T>& rhs){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>& _Str<T>::operator=(const _Str<T>& rhs)\n");
#endif  if (&rhs != this){Clear();if (rhs._nLength > 0)Add(rhs.Data, rhs._nLength);}return *this;}inline _Str<T>& operator+=(const _Str<T>& rhs){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>& _Str<T>::operator+=(const _Str<T>& rhs)\n");
#endif  Add(rhs.Data, rhs._nLength);return *this;}/// <summary>/// 如果不定義operator+=(const const T* psz)/// _Str<T>  s; ///  s+=L"abc";  =>> tmp = _Str<T>(L"abc") => s += tmp;/// 編譯器會把L"abc" 用構造函數轉換成_Str<T>再用加,多了中間環節,缺少效率,/// 而用explicit禁止隱式轉換時,又為很麻煩! 例如: _Str<T> fun();  return L"abc"   編譯不了。/// </summary>/// <param name="psz"></param>/// <returns></returns>inline _Str<T>& operator+=(const T* psz){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t _Str<T>& _Str<T>::operator+=(const T* psz)\n");
#endif  Add(psz);return *this;}/// <summary>/// 強制類型轉換  char_ *p = (char_ *) this;/// 或在函數調用中參數類型為 const char_ *p 時 ,而當你傳入的類型為 str_時,編譯器自動會把 str_ 類型轉換為 str_._pData ;/// </summary>inline operator const T* () const { return _pData; }friend _Str<T> operator + (const _Str<T>& sLeft, const _Str<T>& sRight) {_Str<T> sResult(sLeft._nLength + sRight._nLength);sResult.Add(sLeft);sResult.Add(sRight);return sResult;}//如果沒有下面兩個友元函數,語句: _Str<T> s = "0" + _Str<T>("1") + "2" + "3"; 產生 10  _Str<T> 對象, 有則只產生 7 個 _Str<T> 對象	friend _Str<T> operator + (const _Str<T>& sLeft, const int& iRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline friend _Str<T> operator + (const _Str<T>& sLeft, const T* sRigth)\n");
#endif  _Str<T> sResult(sLeft.Data, 15);sResult.Add(_Str<T>::Java_valueOf(iRigth));return sResult;}/// <summary>///  為了提交效率,否則這個友無涵數可以不能寫,只用///  friend _Str<T> operator + (const _Str<T>& sLeft, const _Str<T>& sRigth);///  就可以了/// </summary>/// <param name="sLeft"></param>/// <param name="sRigth"></param>/// <returns></returns>/// 創建時間: 2022-11-10     最后一次修改時間:2022-11-10inline friend _Str<T> operator + (const  T* sLeft, const _Str<T>& sRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline friend _Str<T> operator + (const  T* sLeft, const _Str<T>& sRigth)\n");
#endif  if (sLeft == null) { return sRigth; }int n = _Math::strLen_t<T>(sLeft);if (n == 0) return sRigth;_Str<T> sResult(sLeft, sRigth.Length);sResult.Add(sRigth);return sResult;}inline friend _Str<T> operator + (const _Str<T>& sLeft, const T* pszRight){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline friend _Str<T> operator + (const _Str<T>& sLeft, const T*  pszRight)\n");
#endif  if (pszRight == null) { return sLeft; }int n = _Math::strLen_t<T>(pszRight);if (n == 0) return sLeft;_Str<T> sResult(sLeft.Length + n + 15);sResult.Add(sLeft);sResult.Add(pszRight, n);return sResult;}#ifdef _CLR_inline friend _Str<T> operator + (const _Str<T>& sLeft, String^ sRight){_Str<T> sResult(sLeft.Data, sRight->Length);sResult.Add(sRight);return sResult;}inline friend _Str<T> operator + (String^ sLeft, const _Str<T>& sRight){_Str<T> sResult(_t(""), sLeft->Length + sRight._nLength);sResult.Add(sLeft);sResult.Add(sRight);return sResult;}inline friend bool operator==(const _Str<T>& sLeft, String^ sRight){return sLeft == _Str<T>(sRight);}inline friend bool operator==(String^ sLeft, const _Str<T>& sRight){return _Str<T>(sLeft) == sRight;}
#endif/// <summary>///  為了提交效率,否則這個友無涵數可以不能寫,只用///  friend _Str<T> operator + (const _Str<T>& sLeft, const _Str<T>& sRigth);///  就可以了/// </summary>/// <param name="sLeft"></param>/// <param name="sRigth"></param>/// <returns></returns>/// 創建時間: 2022-11-10     最后一次修改時間:2022-11-10friend bool operator > (const _Str<T>& sLeft, const _Str<T>& sRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t bool operator > (const str_& sLeft, const str_& sRigth)\n");
#endif //  _STR__DEBUG_return _Math::strCmp_t<T>(sLeft.Data, sRigth.Data) > 0;}friend bool operator < (const _Str<T>& sLeft, const _Str<T>& sRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t bool operator > (const _Str<T>& sLeft, const _Str<T>& sRigth)\n");
#endif  return _Math::strCmp_t<T>(sLeft.Data, sRigth.Data) < 0;}friend bool operator == (const _Str<T>& sLeft, const _Str<T>& sRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t bool operator < (const _Str<T>& sLeft, const _Str<T>& sRigth)\n");
#endif  return _Math::strCmp_t<T>(sLeft.Data, sRigth.Data) == 0;}friend bool operator != (const _Str<T>& sLeft, const _Str<T>& sRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t bool operator < (const _Str<T>& sLeft, const _Str<T>& sRigth)\n");
#endif  return _Math::strCmp_t<T>(sLeft.Data, sRigth.Data) != 0;}/// <summary>/// /// </summary>/// <param name="sLeft"></param>/// <param name="sRigth"></param>/// <returns></returns>/// 創建時間: 2021-10-27      最后一次修改時間:2021-10-27friend bool operator == (const _Str<T>& sLeft, const T* sRigth){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t bool operator == (const _Str<T>& sLeft, const T* sRigth)\n");
#endif  return _Math::strCmp_t<T>(sLeft.Data, sRigth) == 0;}/// <summary>/// /// </summary>/// <param name="sLeft"></param>/// <param name="sRigth"></param>/// <returns></returns>/// 創建時間: 2024-04-19      最后一次修改時間:2024-04-19friend bool operator != (const _Str<T>& sLeft, const T* sRigth){return _Math::strCmp_t<T>(sLeft.Data, sRigth) != 0;}friend bool operator >= (const _Str<T>& sLeft, const T* sRigth){int n = _Math::strCmp_t<T>(sLeft.Data, sRigth);return (n > 0 || n == 0);}friend bool operator <=  (const _Str<T>& sLeft, const T* sRigth){int n = _Math::strCmp_t<T>(sLeft.Data, sRigth);return (n < 0 || n == 0);}public://-----------------------------------------------------------------------------重寫/// <summary>/// 添加字符串,充許pData == null 或者 nLength = 0/// </summary>/// <param name="pData"></param>/// <param name="nLength"></param>/// <returns></returns>/// 創建時間: ????-??-??     最后一次修改時間:2022-10-30 2023-03-21inline const _Str<T>& Add(const T* pData, const int nLength){//_pin(pData);//_cout << _t("_Str<T>:\t inline const T* Add(const T* pData, const int nLength) 參數:") <<  _geti(nLength) << _t("\n");
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline const T* Add(const T* pData, const int nLength) 參數:") << _geti(nLength) << _t("\n");
#endif //要判斷 *pData == 0 防止  str_.Add(L"\0",1); if (pData == null || nLength <= 0 || *pData == 0) { return *this; }if (_nBuffer >= nLength){_Memory::Copy<T>(_pData + _nLength, pData, nLength);_nBuffer -= nLength;_nLength += nLength;}else{/*T* pNew = _Memory::New<T>(this->_nDefaultBuffer + _nLength + nLength + 1, false);if (_nLength > 0)_Memory::Copy<T>(pNew, _pData, _nLength);    //拷貝原來的數據_Memory::Copy<T>(pNew + _nLength, pData, nLength); //拷貝新的內存_Memory::Delete<T>(_pData, _nLength + _nBuffer + 1);  //釋放內存_nLength += nLength;_nBuffer = this->_nDefaultBuffer;_pData = pNew;*///SetBuffer(nLength + _nDefaultBuffer); //舊版本SetBuffer(nLength + _nDefaultBuffer * _Math::pow(2, _nAutoBufferCount)); //自動設置緩沖次數加 if (_nBuffer >= nLength){_Memory::Copy<T>(_pData + _nLength, pData, nLength);_nBuffer -= nLength;_nLength += nLength;}else{throw _t("設置緩沖區失敗!");}++_nAutoBufferCount;  //設置緩沖次數加1}_pData[_nLength] = 0;return *this;}inline  const _Str<T>& Add(const T* pStr) { return Add(pStr, _Math::strLen_t<T>(pStr)); }inline  const _Str<T>& Add(const _Str<T>& rs) { return Add(rs._pData, rs._nLength); }/// <summary>/// 添加一個字符,此函數會忽略  T == 0 的字符結束標志。/// </summary>/// <param name="aChar"></param>/// <returns></returns>/// 創建時間: 2022-12-08      最后一次修改時間:2022-12-08inline  const _Str<T>& Add(const T& aChar){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline  const _Str<T>& Add(const T& aChar) 參數:") << _geti(aChar) << _t("\n");
#endif //要判斷 *pData == 0 防止  str_.Add(L"\0",1); if (aChar == 0) { return *this; }if (_nBuffer >= 1){_pData[_nLength] = aChar;_nBuffer -= 1;_nLength += 1;_pData[_nLength] = 0;}else{SetBuffer(1 + _nDefaultBuffer * _Math::pow(2, _nAutoBufferCount)); //自動設置緩沖次數加 if (_nBuffer >= 1){_pData[_nLength] = aChar;_nBuffer -= 1;_nLength += 1;_pData[_nLength] = 0;}else{throw _t("設置緩沖區失敗!");}++_nAutoBufferCount;}return *this;}inline  const _Str<T>& del(const int& nStartPos, const int& nLength){if (nStartPos + nLength > _nLength){_nBuffer = _nBuffer + _nLength - nStartPos;_nLength = nStartPos + 1;}else if (nStartPos + nLength >= _nLength){_nLength -= nLength;_nBuffer += nLength;}else{for (int n = nStartPos + nLength; n < _nLength; ++n){_pData[n - nLength] = _pData[n];}_nLength -= nLength;_nBuffer += nLength;}return *this;}/// <summary>/// 初始化數據,并設置緩沖區大小,如果設置bInitValue == true,/// 則所有緩沖都會用 tValue填充,這時長度是:nBuffer。/// </summary>/// <param name="nBuffer"></param>/// <param name="tValue"></param>/// <param name="bInitValeu"></param>/// 創建時間: ????-??-??      最后一次修改時間:2024-04-21inline void InitData(const int& nBuffer,const T& tValue = 0, const bool bInitValue = false){
#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline void InitData(const int& nBuffer) 參數:") << _geti(nBuffer) << _t("\n");
#endif if (nBuffer < 0) {throw _t("_Str<T>::InitData錯誤: nBuffer < 0");}if (bInitValue){_nLength = nBuffer;_nBuffer = 0;_pData = _Memory::New<T>(_nLength + 1);for (int i = 0; i < _nLength; ++i){_pData[i] = tValue;}_pData[_nLength] = 0;}else{_nLength = 0;_nBuffer = nBuffer;_pData = _Memory::New<T>(_nBuffer + 1);_pData[0] = 0;}}/// <summary>/// 清空內容,但并不釋放內存,所有數據變緩沖。/// </summary>inline void Clear(){
#ifdef  _STR_DEBUG__cout << _t("_Str<T> :  void ClearData()\n");
#endif  //不充許出現null指針_nBuffer = _nLength + _nBuffer;_nLength = 0;if(_nBuffer > 0)_pData[0] = 0;}inline void ClearMemory(){_Memory::Delete<T>(_pData, _nLength + _nBuffer + 1);_pData = null;_nLength = 0;_nBuffer = 0;}/// <summary>/// 設置緩沖數量/// </summary>/// <typeparam name="T"></typeparam>/// 創建時間: ????-??-??      最后一次修改時間:2022-11-17inline void SetBuffer(const int& nBuffer){
#ifdef _STR_DEBUG__cout << _t("_Str<T>:\t inline void SetBuffer(const int& nBuffer)參數:") << _geti(nBuffer) << "\n";
#endifif (nBuffer <= 0 || nBuffer <= _nBuffer) return;T* pNew = _Memory::New<T>(_nLength + nBuffer + 1); //分配新內存,這里分配內存時注意要加 1if (_nLength > 0)//拷貝舊數據{_Memory::Copy(pNew, _pData, _nLength);}_Memory::Delete<T>(_pData, _nLength + _nBuffer + 1);  //空字符點一位_pData = pNew;_nBuffer = nBuffer;_pData[_nLength] = 0;  //設置一下結束字符}/// <summary>/// 重新設置字符串長度,這個長度不能大于原字符長度加上緩沖數量之和/// </summary>/// <param name="nNewLength"></param>/// 創建時間: ????-??-??      最后一次修改時間:2022-05-12inline void SetNewLength(const int& nNewLength){assert(nNewLength <= _nLength + _nBuffer && nNewLength >= 0);_nBuffer = _nBuffer - nNewLength + _nLength;_nLength = nNewLength;_pData[nNewLength] = 0;}/// <summary>/// 補位4,用0替代,返回一個副本,例如:/// 1 => 0001/// 10 => 0010/// 99999 => 9999/// </summary>/// <param name="nCount"></param>/// <returns></returns>_Str<T> intStrFillUp(int nCount = 4) const{if (nCount <= 0)  return _t("");if (nCount > _nLength){_Str<T> sResult(_t(""), nCount);for (int i = 1; i <= nCount - _nLength; ++i) {sResult.Add(_t('0'));}for (int i = 0; i < _nLength; ++i) {sResult.Add(_pData[i]);}return sResult;}else{return _Str<T>(_pData, _nLength, _nLength - nCount, nCount);}}public:/// <summary>/// 保留小數位,四舍五入/// </summary>/// <param name="dNumber">保留小數位的數字</param>/// <param name="nDigitsCount">保留小數的位數</param>/// <returns></returns>/// 創建時間: ????-??-??      最后一次修改時間:2021-11-02static _Str<T> KeepSmallDigits(const double& dNumber, const int nDigitsCount){assert(nDigitsCount < 30);_Str<T> sResult(50);_Mem<T> m(50);__int64 iNumber = (__int64)dNumber;//取整數部分sResult.Add(_Math::IntToStr(iNumber, m.Data));if (nDigitsCount == 0)return sResult;else{sResult.Add(_t("."));iNumber = (__int64)((dNumber - iNumber) * _Math::pow(10, nDigitsCount + 1)); //取小數部份+1位//四舍五入if (_Math::digitsOf(iNumber, 1) >= 5)iNumber = (iNumber / 10 + 1) * 10;iNumber = iNumber / 10;if (iNumber == 0)  //小數部分==0{for (int n = 0; n < nDigitsCount; ++n){sResult.Add(_t('0'));}}else{sResult.Add(_Math::intToStr(iNumber, m.Data));}}return sResult;}//----------------------------------------------------------------------------------------------------功能函數/// <summary>/// 除例外字符串的長度/// </summary>/// <param name="pCharArray"></param>/// <returns></returns>inline int Length_except(const T* pCharArray)const{int n = 0;for (int i = 0; i < _nLength; ++i) {T ch = _pData[i];if (_Math::strChr(pCharArray, ch) == -1) {++n;}}return n;}/// <summary>/// 子字符串是從字符位置 iStart 開始并跨越 iLength 個字符(或直到字符串末尾,以先到者為準)的對象部分。	 /// </summary>/// <typeparam name="T"></typeparam>/// 創建時間: ????-??-??      最后一次修改時間:2024-05-13inline _Str<T> SubStr(const int iStart, const int iLength) const { if (iStart >= _nLength || iLength <= 0)return _Str<T>();int nTrueStart = iStart > 0 ? iStart : 0;int nTrueLength = (nTrueStart + iLength <= _nLength) ? iLength : _nLength - nTrueStart;return _Str<T>(_pData, _nLength, nTrueStart, nTrueLength);}/// <summary>/// 返回全是大寫字母的拷貝/// </summary>/// <returns></returns>/// 創建時間: 2023-03-25      最后一次修改時間:2023-03-25 inline _Str<T> Upper()const{_Str<T> sResult;sResult.SetBuffer(_nLength);for (int i = 0; i <= _nLength; ++i){sResult._pData[i] = gs.c_ToUpper(_pData[i]);}sResult._nLength = _nLength;sResult._nBuffer = 0;return sResult;}/// <summary>/// 返回全是小寫字母的持由/// </summary>/// <returns></returns>/// 創建時間: 2023-03-25      最后一次修改時間:2023-03-25 inline _Str<T> Lower()const{_Str<T> sResult;sResult.SetBuffer(_nLength);for (int i = 0; i <= _nLength; ++i){sResult._pData[i] = gs.c_ToLower(_pData[i]);}sResult._nLength = _nLength;sResult._nBuffer = 0;return sResult;}//添加換行符inline void Newline() { Add('\n'); }//添加水平制表鍵inline void HorizontalTab() { Add('\t'); }//添加垂直制表鍵inline void VerticalTab() { Add('\v'); };//添加退格鍵inline void Backspace() { Add('\b'); }//添加回車鍵inline void CarriageReturn() { Add('\r'); }//添加進紙鍵inline void Formfeed() { Add('\f'); }//添加響鈴符inline void Alert() { Add('\a'); }//添加反斜杠鍵inline void Backslash() { Add('\\'); }//添加問號inline void QuestionMark() { Add('\?'); }//添加單引號inline void SingleQuote() { Add('\''); }//添加雙引號inline void DoubleQuote() { Add('\"'); }public://---------------------------------------------------------------------------------- C++ Std:string 方法/// <summary>/// 返回數據指針/// </summary>/// <returns></returns>inline const T* std_c_str() const { return  _pData; }/// <summary>/// /// </summary>/// <returns></returns>inline size_t std_size() const { return _nLength; }/// <summary>/// 返回在不重新分配內存時可存儲字符的最大個數/// </summary>/// <returns>返回string分配的存儲容量</returns>inline int std_capacity()const { return _nLength + _nBuffer; }/// <summary>/// 字符串長度/// </summary>/// <returns></returns>inline int std_Length()const { return _nLength; }/// <summary>/// 添加 nCount 個字符串/// </summary>/// <param name="str"></param>/// <param name="nCount"></param>/// 創建時間: 2022-12-08      最后一次修改時間:2022-12-08inline const  _Str<T>& AppendCount(const _Str<T> &str, const int nCount){if (nCount >= 0 && str._nLength > 0){SetBuffer(str._nLength * nCount + _nDefaultBuffer);for (int i = 0; i < nCount; ++i) { Add(str); }}return *this;}inline  const _Str<T>& std_append(const T& aChar) { return Add(aChar); }inline  const _Str<T>& std_append(const T* pStr) { return Add(pStr); }inline  const _Str<T>& std_append(const T* pStr, const int nCount) { return Add(pStr, nCount); }inline  const _Str<T>& std_append(const _Str<T>& rs) { return Add(rs); }/// <summary>/// 返回一個新構造的字符串對象,其值初始化為此對象的子字符串的副本,相當于區間 [pos1,pos2] 相當于 SubStr(pos1,pos2-pos1+1)/// 子字符串是從字符位置 pos 開始并跨越 len 個字符(或直到字符串末尾,以先到者為準)的對象部分。	 /// </summary>/// <typeparam name="T"></typeparam>inline _Str<T> std_substr(const int iStart, const int iLength) const { return SubStr(iStart, iLength); }/*a) =, assign() //賦以新值b) swap() //交換兩個字符串的內容c) +=, append(), push_back() //在尾部添加字符d) insert() //插入字符e) erase(int nStart, int nEnd) //刪除nStart—nEnd位置字符f) clear() //刪除全部字符g) replace() //替換字符h) + //串聯字符串i) == , != , <, <= , >, >= , compare() //比較字符串j) size(), _nLength //返回字符數量k) Maxsize() //返回字符的可能最大個數l) empty() //判斷字符串是否為空m) capacity() //返回重新分配之前的字符容量n) reserve() //保留一定量內存以容納一定數量的字符o)[], at() //存取單一字符p) >> , getline() //從stream讀取某值q) << //將謀值寫入streamr) copy() //將某值賦值為一個C_strings) c_str() //將內容以C_string返回t) data() //將內容以字符數組形式返回u) SubStr() //返回某個子字符串v)查找函數w)begin() end() //提供類似STL的迭代器支持x) rbegin() rend() //逆向迭代器y) get_allocator() //返回配置器*///從nStart開始向后查找字符c在當前字符串的位置inline int std_find(const T& c, const int& nStart = 0) const { return _Math::find<T>(&c, nStart, 1); }//從nStart開始向后查找字符串s在當前串中的位置inline int std_find(const T* pFindStr, const int& nStart = 0) const { return _Math::find<T>(pFindStr, nStart, _Math::strLen_t<T>(pFindStr)); }//從nStart開始向后查找字符串s中前nFindLength個字符在當前串中的位置inline int std_find(const T* pFindStr, const int& nStart, const int& nFindLength) const { return find_(pFindStr, nStart, nFindLength); }//從pos開始向后查找字符串s在當前串中的位置inline int std_find(const _Str<T>& s, const int& nStart = 0) const { return _Math::find<T>(_pData,_nLength,s._pData,s._nLength, nStart); }/// <summary>/// std::string::rfind是一個字符串類成員函數,用于搜索字符串中任何字符的最后出現。/// 如果字符存在于字符串中,則它返回該字符在字符串中最后一次出現的索引,否則它將返/// 回string::npos,它指示指針位于字符串的末尾。/// </summary>/// <param name="c"></param>/// <param name="nStart"></param>/// <returns></returns>inline int std_rfind(T c, const int& rStart = 0) const { return _Math::rfind<T>(_pData, _nLength, &c, 1, rStart); }inline int std_rfind(const T* pFindStr, const int& rStart = 0) const { return _Math::rfind<T>(_pData,_nLength,pFindStr, _Math::strLen_t<T>(pFindStr), rStart);}inline int std_rfind(const T* pFindStr, const int& nLength, const int& rStart = 0) const { return _Math::RFind<T>(_pData, _nLength, pFindStr, nLength, rStart); }inline int std_rfind(const _Str<T>& s, const int& rStart = 0) const { return _Math::rfind<T>(_pData, _nLength, s._pData,s._nLength, rStart); }//從nStart開始向后查找字符c第一次出現的位置inline int std_find_First_of(T c, const int& nStart = 0) const { return std_find_First_of_(c, nStart); }int std_find_First_of(const T* pStr, const int& nStart = 0) const { return std_find_First_of_(pStr, nStart, _Math::strLen_t<T>(pStr)); }int std_find_First_of(const T* pStr, const int& nStart, const int& nFindLength) const { return std_find_First_of_(pStr, nStart, nFindLength); }int std_find_First_of(const _Str<T>& s, const int& nStart = 0) const { return std_find_First_of_(s, nStart); }//從nStart開始向后查找字符c第一次沒有出現的位置inline int std_find_First_not_of(T c, const int& nStart = 0) const { return std_find_First_not_of_(c, nStart); }int std_find_First_not_of(const T* pStr, const int& nStart = 0) const { return std_find_First_not_of_(pStr, nStart, _Math::strLen_t<T>(pStr)); }int std_find_First_not_of(const T* pStr, const int& nStart, const int& nFindLength) const { return std_find_First_not_of_(pStr, nStart, nFindLength); }int std_find_First_not_of(const _Str<T>& s, const int& nStart = 0) const { return std_find_First_not_of_(s, nStart); }//從nStart開始向前查找字符c第一次出現的位置inline int std_find_last_of(const T& c, const int& nStart = this->npos) const { return std_find_last_of_(c, nStart); }int std_find_last_of(const T* pStr, const int& nStart = this->npos) const { return std_find_last_of_(pStr, nStart, _Math::strLen_t<T>(pStr)); }int std_find_last_of(const T* pStr, const int& nStart, const int& nFindLength) const { return std_find_last_of_(pStr, nStart, nFindLength); }int std_find_last_of(const _Str<T>& s, const int& nStart = this->npos) const { return std_find_last_of_(s, nStart); }//從nStart開始向前查找字符c第一次沒有出現的位置inline int std_find_last_not_of(T c, const int& nStart = this->npos) const { return std_find_last_not_of_(c, nStart); }int std_find_last_not_of(const T* pStr, const int& nStart = this->npos) const { return std_find_last_not_of_(pStr, nStart, _Math::strLen_t<T>(pStr)); }int std_find_last_not_of(const T* pStr, const int& nStart, const int& nFindLength) const { return std_find_last_not_of_(pStr, nStart, nFindLength); }int std_find_last_not_of(const _Str<T>& s, const int& nStart = this->npos) const { return std_find_last_not_of_(s, nStart); }/// <summary>/// std::string::erase 是 C++ 標準庫中的一個成員函數,用于刪除字符串中指定范圍的字符。/// 其中,pos 是要刪除字符的起始位置,count 是要刪除的字符數。如果不提供 count 參數,/// 則默認刪除從 pos 開始到字符串末尾的所有字符。函數返回對修改后的字符串的引用。/// </summary>/// <param name="pos"></param>/// <param name="count"></param>/// <returns></returns>/// 創建時間: 2024-04-21      最后一次修改時間:2024-04-21_Str<T>& std_erase(const size_t& pos = 0, const size_t& count = npos) {if (pos < _nLength){if (pos + count < _nLength){for (size_t n = pos; n < pos + count; n++) {_pData[n] = 0;		}_nLength -= count;_nBuffer += count;}else {for (size_t n = pos; n < _nLength; n++) {_pData[n] = 0;}_nLength = pos;_nBuffer = _nLength - pos;}}return *this;}/// <summary>/// 模擬std::string::erase/// </summary>/// <param name="first"></param>/// <param name="last"></param>/// <returns></returns>/// 創建時間: 2024-04-21      最后一次修改時間:2024-04-22_Str<T>& std_erase(const _iterator<T>& first, const _iterator<T>& last) {/*std::string s1 = "0abc023030000";s1.erase(std::find_if(s1.rbegin(), s1.rend(),[](char ch) { return ch != '0'; }).base(), s1.end());std::cout << "s1=" << s1 << "\n";_string s2 = _t("0abc023030000");s2.std_erase(lf::_find_if(s2.std_rbegin(), s2.std_rend(),[](wchar_t ch) { return ch != _t('0'); }).std_base(), s2.std_end());std::wcout << _t("s2=") << s2 << _t("\n");*/_Str<T> tmp(_t(""), _nLength);const T* pf = first;T* pl = (T*)(const T*)last;int n = pf - _pData;//拷貝前半部分if (n > 0){for (int i = 0; i < n; ++i){tmp.Add(*(_pData + i));}}++pl;//拷貝后半部分while (*pl)	{tmp.Add(*pl);++pl;}//清除字符,注意,在這里不要清除內存this->Clear();this->Add(tmp); //拷貝進來return *this;}/// <summary>/// std::string::begin() 是 C++ 標準庫中的一個成員函數,/// 用于返回指向字符串中第一個字符的迭代器/// </summary>/// <returns></returns>/// 創建時間: 2024-04-21      最后一次修改時間:2024-04-21const _iterator<T> std_begin() const noexcept { return _pData; }/// <summary>/// std::string::end() 是 C++ 標準庫中的一個成員函數,用于返回指/// 向字符串中最后一個字符之后的迭代器/// </summary>/// <returns></returns>/// 創建時間: 2024-04-21      最后一次修改時間:2024-04-21const _iterator<T> std_end() const noexcept { return _pData + _nLength; }/// <summary>/// std::string::rbegin() 是 C++ 標準庫中的一個成員函數,用于返回指/// 向字符串中最后一個字符的逆向迭代器,指針指向最后一個 T 的 下一位置,/// 即是字符串結束符的 #0。/// </summary>/// <returns></returns>/// 創建時間: 2024-04-21      最后一次修改時間:2024-04-22const _reverse_iterator<T> std_rbegin() const noexcept { return (_reverse_iterator<T>)(_pData + _nLength); }/// <summary>/// std::string::rend() 是 C++ 標準庫中的一個成員函數,用于返回指向字符串中/// 第一個字符之前的逆向迭代器。它的原型如下/// </summary>/// <returns></returns>const _reverse_iterator<T> std_rend() const noexcept { return (_reverse_iterator<T>)(_pData); }public://--------------------------------------------------------------------------------模似CSharp字符串_Str<T>//// 摘要://     報告指定字符在此實例中的第一個匹配項的從零開始的索引。 搜索從指定字符位置開始,并檢查指定數量的字符位置。//// 參數://   value://     要查找的 Unicode 字符。////   startIndex://     搜索起始位置。////   count://     要檢查的字符位置數。//// 返回結果://     如果找到該字符,則為從字符串的起始位置開始的 value 從零開始的索引位置;否則為 -1。//// 異常://   T:System.ArgumentOutOfRangeException://     count 或 startIndex 為負數。 - 或 - startIndex 大于此字符串的長度。 - 或 - count 大于此字符串的長度減 startIndex。/// <summary>/// /// </summary>/// <param name="value"></param>/// <param name="startIndex"></param>/// <param name="count"></param>/// <returns></returns>/// 創建時間: 2021-10-28      最后一次修改時間:2021-10-28    優化測式: 否//inline int CSharp_IndexOf(const T& value, const int& startIndex, const int& count) const//{//return _Math::find<T>(&value, 1, _pData, count, startIndex);//return -1;//}//// 摘要://     報告指定 Unicode 字符在此字符串中的第一個匹配項的從零開始的索引。 該搜索從指定字符位置開始。//// 參數://   value://     要查找的 Unicode 字符。////   startIndex://     搜索起始位置。//// 返回結果://     如果找到該字符,則為從字符串的起始位置開始的 value 從零開始的索引位置;否則為 -1。//// 異常://   T:System.ArgumentOutOfRangeException://     startIndex 小于 0(零)或大于此字符串的長度。int CSharp_IndexOf(const T& value, const int& startIndex) const	{ return CSharp_indexOf(value, startIndex, this->_nLength - startIndex - 1);}//// 摘要://     報告指定字符串在此實例中的第一個匹配項的從零開始的索引。//// 參數://   value://     要搜尋的字符串。//// 返回結果://     如果找到該字符串,則為 value 的從零開始的索引位置;如果未找到該字符串,則為 -1。 如果 value 為 System._Str<T>.Empty,則返回值為//     0。//// 異常://   T:System.ArgumentNullException://     value 為 null。inline int CSharp_IndexOf(const _Str<T>& value) const{	return std_find(value); }//// 摘要://     報告指定字符串在此實例中的第一個匹配項的從零開始的索引。 該搜索從指定字符位置開始。//// 參數://   value://     要搜尋的字符串。////   startIndex://     搜索起始位置。//// 返回結果://     如果找到該字符串,則為從當前實例的起始位置開始的從零開始的 value 的索引位置;否則為 -1。 如果 value 為 System._Str<T>.Empty,則返回值為//     startIndex。//// 異常://   T:System.ArgumentNullException://     value 為 null。////   T:System.ArgumentOutOfRangeException://     startIndex 小于 0(零)或大于此字符串的長度。inline int CSharp_IndexOf(const _Str<T>& value, const int& startIndex) const{	return std_find(value, startIndex);	}//// 摘要://     報告指定字符串在此實例中的第一個匹配項的從零開始的索引。 搜索從指定字符位置開始,并檢查指定數量的字符位置。//// 參數://   value://     要搜尋的字符串。////   startIndex://     搜索起始位置。////   count://     要檢查的字符位置數。//// 返回結果://     如果找到該字符串,則為從當前實例的起始位置開始的從零開始的 value 的索引位置;否則為 -1。 如果 value 為 System._Str<T>.Empty,則返回值為//     startIndex。//// 異常://   T:System.ArgumentNullException://     value 為 null。////   T:System.ArgumentOutOfRangeException://     count 或 startIndex 為負數。 - 或 - startIndex 大于此字符串的長度。 - 或 - count 大于此字符串的長度減 startIndex。inline int CSharp_IndexOf(const _Str<T>& value, const int& startIndex, const int& count) const{assert(startIndex + count <= this->_nLength);return -1;}//int indexOf(const _Str<T>& value, StringComparison comparisonType) const;//int indexOf(const _Str<T>& value, const int& startIndex, StringComparison comparisonType) const;//// 摘要://     報告指定 Unicode 字符在此字符串中的第一個匹配項的從零開始的索引。//// 參數://   value://     要查找的 Unicode 字符。//// 返回結果://     如果找到該字符,則為 value 的從零開始的索引位置;如果未找到,則為 -1。inline int CSharp_IndexOf(const T& value) const { return _Math::strChr_t<T>(_pData, value); }//int indexOf(const _Str<T>& value, const int&  startIndex, const int&  count, StringComparison comparisonType) const;//int indexOfAny(char[] anyOf, const int&  startIndex, const int&  count) const;     //int indexOfAny(char[] anyOf, const int&  startIndex) const;//int indexOfAny(char[] anyOf) const;inline _Str<T> CSharp_Substring(const int& startIndex, const int& length) const{return _Str<T>(_pData, _nLength, startIndex, length);}inline _Str<T> CSharp_Substring(const int& startIndex)const{return _Str<T>(_pData, this->_nLength, startIndex, _nLength);}/// <summary>/// 返回除去兩邊的空格和控制字符/// </summary>/// <returns></returns>/// 創建時間:  2022-10-06  最后一次修改時間:  2022-10-06 已測試inline _Str<T> CSharp_Trim()const{int nStart = 0;  int nEnd = 0;bool bFind = false;for (nStart = 0; nStart < _nLength; ++nStart){T c = _pData[nStart];if (!gcf.gcf_iscntrl(c) && c != _t(' ')) { bFind = true;  break; }}//if (nStart == _nLength - 1) return  _string();   //錯,當字符是 1 個是時,任何情況  nStart == 0 成立if (nStart == _nLength - 1){if (bFind) {return *this;}else {return  _Str<T>();}}bFind = false;for (nEnd = _nLength - 1; nEnd >= nStart; --nEnd){T c = _pData[nEnd];if (!gcf.gcf_iscntrl(c) && c != _t(' ')) { break; }}int nCopyLength = nEnd - nStart + 1;if (nCopyLength <= 0) return  _Str<T>();return CSharp_Substring(nStart, nCopyLength);}/// <summary>/// 除去右邊連續的tChar字符,例 :/// abcaa.TrimRight('a') == abc/// abcaaba.TrimRight('a') = abcaab/// </summary>/// <param name="tChar"></param>/// <returns></returns>/// 創建時間:  2024-04-25  最后一次修改時間:  2024-04-25 已測試inline _Str<T> TrimRight(const T& tChar){ 		 int n = 0;for(int i = _nLength - 1; i >= 0; --i){if (_pData[i] == tChar){_pData[i] = 0;++n;}else{break;}}_nBuffer += n;_nLength -= n;return *this;}/// <summary>/// 返回小寫副本/// </summary>/// <returns></returns>/// 創建時間:  2022-10-06  最后一次修改時間:  2022-10-06inline _Str<T> CSharp_ToLower() const{_Str<T> sResult(_t(""), _nLength + 1);for (int i = 0; i < _nLength; ++i) { sResult._pData[i] = gs.c_ToLower(_pData[i]); }sResult._nBuffer = 0;sResult._nLength = _nLength;sResult._pData[_nLength] = 0;return sResult;}/// <summary>/// 返回大寫副本/// </summary>/// <returns></returns>inline _Str<T> CSharp_ToUpper()const{_Str<T> sResult(_t(""), _nLength + 1);for (int i = 0; i < _nLength; ++i) { sResult._pData[i] = gs.c_ToUpper(_pData[i]); }sResult._nBuffer = 0;sResult._nLength = _nLength;sResult._pData[_nLength] = 0;return sResult;}/*/// <summary>/// /// </summary>/// <param name="sSub"></param>/// <returns></returns>/// 創建時間:  2022-10-06  最后一次修改時間:  2022-10-06   已測試 int CSharp_IndexOf(const _Str<T>& sSub)const{if (_nLength == 0 || sSub._nLength == 0) return -1;const int nEnd = _nLength - sSub._nLength;if (nEnd < 0) return -1;for (int i = 0; i <= nEnd; ++i) {bool bFind = true;for (int j = 0; j < sSub._nLength; ++j){if (_pData[i + j] != sSub._pData[j]){bFind = false;break;}}if (bFind) return i;}return -1;}*//// <summary>/// 返回一個新字符串,其中當前實例中出現的所有指定字符串都替換為另一個指定的字符串。/// </summary>/// <param name="oldValue"></param>/// <param name="newValue"></param>/// <returns></returns>/// 創建時間:  2022-12-04  最后一次修改時間:  2022-12-04  已測試_Str<T> CSharp_Replace(const _Str<T>& oldValue,const _Str<T>& newValue){_Str<T> sResult(_t(""), _nLength + newValue._nLength);int iCopyStart = 0;int i = std_find(oldValue);while (i != -1){ if (i - iCopyStart > 0)sResult.Add(SubStr(iCopyStart, i - iCopyStart));sResult.Add(newValue);iCopyStart = i + oldValue._nLength;i = std_find(oldValue, i + oldValue._nLength);}if(_nLength - iCopyStart > 0)sResult.Add(SubStr(iCopyStart, _nLength - iCopyStart));return sResult;}/// <summary>/// 字符串長度/// </summary>__declspec(property(get = GetLength)) const int CSharp_Length;//--------------------------------------------------------------------------------模似Java字符串方法/// <summary>/// /// </summary>/// <param name="nValue"></param>/// <returns></returns>/// 創建時間: 2021-10-04      最后一次修改時間:2021-10-04inline static _Str<T>  Java_valueOf(const __int64& iNumber) {_Mem<T> m(50);_Math::intToStr_t<T>(iNumber, m.Pointer, &m.DataLength);return _Str<T>(m.Pointer, m.DataLength, 0, m.DataLength);}//---------------------------------------------------------------------------------模擬Python字符串方法/// <summary>/// 實現 Python String::title()/// 方法title()以首字母大寫的方式顯示每個單詞,即將每個單詞的首字母都改為大寫,其它改為小寫。/// </summary>/// <returns></returns>/// 創建時間: 2023-03-25      最后一次修改時間:2023-03-25inline _Str<T>  Python_title()const{_Str<T>  sResult = _pData;bool bBegin = false;int iStart = -1;for (int i = 0; i < _nLength; ++i){			if (gs.c_IsEnglishLetters(_pData[i])){if (!bBegin){bBegin = true;iStart = i;}				}else{ if (bBegin){sResult._pData[iStart] = gs.c_ToUpper(_pData[iStart]);bBegin = false;					 }	}}//最后一個字符 例 One of Python's 中的 s if(iStart != -1)sResult._pData[iStart] = gs.c_ToUpper(_pData[iStart]);return sResult;}//--------------------------------------------------------------------------------------------String擴展/// <summary>/// 返回不包含空格的可打印字符/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-02-07      最后一次修改時間:2022-02-07 inline _Str<T> RemoveUnprintableAndWhitespace()const{//StringBuilder^ sbReulst = gcnew StringBuilder(sText->Length);//for each (wchar_t c in sText)//{//    if (c_IsPrintable(c) && (!c_IsWhiteSpace(c)))//        sbReulst->Append(c);//}//return sbReulst->ToString();_Str<T> sResutl(_t(""),_nLength);int i = 0;for(int i = 0; i < _nLength; ++i){_char c = _pData[i];if (gcf.gcf_isprint(c) && (!gcf.gcf_isblank(c)))sResutl.Add(c);}return sResutl;}/// <summary>/// 返回不包含空格和標點符號的可打印字符/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-02-25      最后一次修改時間:2022-02-25 inline _Str<T> RemovePunctuationAndWhitespace(){_Str<T> sResutl(_t(""), _nLength);for(_char c : *this){if (gcf.gcf_isprint(c) && (! gcf.gcf_isblank(c)) && (! gcf.gcf_IsPunctuation(c)))sResutl.append(c);}return sResutl;}/// <summary>/// 檢查是否包含可打印字符/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-01-21      最后一次修改時間:2022-01-21inline bool IsHavePrintableChar(){_char* p = _pData;while (*p){if (gcf.gcf_isprint(*p)) return true;++p;}return false;  }/// <summary>/// 返回清除所有不可打印的字符串的拷貝/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-01-21      最后一次修改時間:2022-01-21inline _Str<T> CleanUpNnprintable() const{_Str<T> sResult(_t(""), _nLength);_char* pText = (_char*)_pData;while (*pText){if (gcf.gcf_isprint(*pText)){sResult.Add(*pText);}++pText;}return sResult;}/// <summary>/// 在sText計算有多少個字符串sSub/// </summary>/// <param name="sText"></param>/// <param name="sSub"></param>/// <returns></returns>inline int StrCount(const _Str<T>& sSub){int n = 0;int i =  CSharp_IndexOf(sSub);while (i != -1){n += 1;i = CSharp_IndexOf(sSub, i + sSub._nLength);}return n;}/// <summary>/// 計算有多少個相同的字符/// </summary>/// <param name="c"></param>/// <returns></returns>inline int StrCount(const _char c){int n = 0;for (int i = 0; i < _nLength; ++i){if (_pData[i] == c) { ++n; }}return n;}/// <summary>/// 在字符串[iFindStart,iFindEnd] 區間內查找字符串第一次出現的位置。/// </summary>/// <param name="sFindString">要查找的字符串</param>/// <param name="iFindStart">查找開始位置</param>/// <param name="iFindEnd">查找結束位置</param>/// <param name="bMatchCase">是否大小字匹配</param>/// <returns>如果找到,返回第一次出現的位置,否則返回-1</returns>/// 創建時間:  2022-12-11      最后一次修改時間:2022-12-11   已測試(2022-12-11)int IndexOf(const _Str<T>& sFindString, const int iFindStart, const int iFindEnd, bool bMatchCase = true) const{ return _Math::StrFindFirst_t<T>(_pData, iFindEnd + 1, sFindString, sFindString._nLength, iFindStart, bMatchCase);}/// <summary>/// 查找字符串第一次出現的位置/// </summary>/// <param name="sFindString">要查找的字符串</param>/// <param name="iFindStart">查找開始處</param>/// <param name="bMatchCase">是否大小寫匹配</param>/// <returns>找到返回第一次出現的位置,沒找到返回-1</returns>/// 創建時間:  2022-12-06      最后一次修改時間:2022-12-06   已測試(2022-12-06)int IndexOf(const _Str<T>& sFindString, const int iFindStart = 0, bool bMatchCase = true) const{return _Math::strFindFirst_t<T>(_pData, _nLength, sFindString, sFindString._nLength, iFindStart, bMatchCase);}/// <summary>/// 返回右邊配對字符的位置/// </summary>/// <param name="sText"></param>/// <param name="nLeftPos"></param>/// <param name="cLeft"></param>/// <returns></returns>/// 創建時間:  2022-12-18      最后一次修改時間:2022-12-18   已測試(2022-12-18)int IndexOfRightPairChar(const int nLeftPos, const _char cLeft, const _char cRight)const{return gs.s_FindRightPairChar_t<T>(_pData, nLeftPos, cLeft, cRight);}/// <summary>/// 查找sFindCharArray任意一個字符在字符串中第一次出現的位置,找到返回位置和找到的字符,找不到第一個結果為-1,第二個為'\0';/// </summary>/// <param name="sFindCharArray"></param>/// <returns></returns>/// 創建時間:  2022-03-01      最后一次修改時間:2023-03-18   已測試(2023-03-18)_Pair<int, T> IndexOfAnyChar(const T* sFindCharArray) const{_Pair<int, T> lpResult(-1, _t('\0'));T* pFind = (T*)sFindCharArray;while (*pFind){int i = 0;T* pText = (T*)_pData; //重置 pTextwhile (*pText){if (*pText == *pFind){lpResult.First = i;lpResult.Second = *pFind;return lpResult;}++pText;++i;}++pFind;}return lpResult;}/// <summary>/// 查找sFindCharArray任意一個字符在字符串中最后一次出現的位置,找到返回位置和找到的字符,找不到第一個結果為-1,第二個為'\0';/// </summary>/// <param name="sFindCharArray"></param>/// <returns></returns>/// 創建時間:  2023-04-22      最后一次修改時間:2023-04-22   已測試(2023-04-22)_Pair<int, T> LastIndexOfAnyChar(const T* sFindCharArray) const{_Pair<int, T> lpResult(-1, _t('\0'));for (int i = _nLength - 1; i >= 0; --i){if ( _Math::strChr_t<T>(sFindCharArray, _pData[i]) != -1){lpResult.First = i;lpResult.Second = _pData[i];return lpResult;}}return lpResult;}/// <summary>/// 查找單個字符/// </summary>/// <param name="c"></param>/// <param name="iFindStart"></param>/// <param name="bMatchCase"></param>/// <returns></returns>/// 創建時間:  2022-12-07      最后一次修改時間:2022-12-07   已測試(2022-12-07)int IndexOf(const T c, const int iFindStart = 0, bool bMatchCase = true) const{		return _Math::strFindFirst_t<T>(_pData, _nLength, &c, 1, iFindStart, bMatchCase);}/// <summary>/// 向函數傳遞一個ch,這個函數參數為_char,返回為bool。/// </summary>/// <typeparam name="fun"></typeparam>/// <param name="iFindStart"></param>/// <param name="f"></param>/// <returns></returns>/// 創建時間:  2024-04-28      最后一次修改時間:2024-04-28   已測試(2024-04-28)template<class fun>int IndexIf(fun f, const int& iFindStart = 0)const{for (int i = iFindStart; i < _nLength; ++i) {if (f(_pData[i]))return i;}return -1;}/// <summary>/// 查找第一個不是ch的字符。/// </summary>/// <param name="ch"></param>/// <param name="iFindStart"></param>/// <returns></returns>/// 創建時間:  2024-04-28      最后一次修改時間:2024-04-28   已測試(2024-04-28)int IndexNotOf(const T& ch, const int& iFindStart = 0)const{  //無法訪問ch//return IndexIf([](const _char& c)->bool { return c != ch; }, iFindStart);for (int i = iFindStart; i < _nLength; ++i) {if (_pData[i] != ch)return i;}return -1;}int IndexOf(const T c, const int iFindStart, const int iFindEnd, bool bMatchCase = true) const{return _Math::strFindFirst_t<T>(_pData, iFindEnd + 1, &c, 1, iFindStart, bMatchCase);}/// <summary>/// 在字符串[iFindStart,iFindEnd] 區間內查找字符串最后一次出現的位置。/// </summary>/// <param name="sFindString">要查找的字符串</param>/// <param name="iFindStart">查找開始位置</param>/// <param name="iFindEnd">查找結束位置</param>/// <param name="bMatchCase">是否大小字匹配</param>/// <returns>如果找到,返回最后一次出現的位置,否則返回-1</returns>/// 創建時間:  2022-12-11      最后一次修改時間:2022-12-11   已測試(2022-12-11)int LastIndexOf(const _Str<T>& sFindString, const int iFindStart, const int iFindEnd, bool bMatchCase = true) const{ return _Math::strFindLast_t<T>(_pData, iFindEnd + 1, sFindString, sFindString._nLength, iFindStart, bMatchCase);}/// <summary>/// 查找最后一次出現的字符串位置/// </summary>/// <param name="sFindString">要查找的字符串</param>/// <param name="iFindStart">查找開始位置</param>/// <param name="bMatchCase">是否大小配置</param>/// <returns></returns>/// 創建時間:  2022-12-07      最后一次修改時間:2022-12-07   已測試(2022-12-07)int LastIndexOf(const _Str<T> &sFindString, const int iFindStart = 0, bool bMatchCase = true) const{return _Math::strFindLast_t<T>(_pData, _nLength, sFindString,sFindString._nLength, iFindStart, bMatchCase);}int LastIndexOf(const T c, const int iFindStart, const int iFindEnd, bool bMatchCase = true) const{return _Math::strFindLast_t<T>(_pData, iFindEnd + 1, &c, 1, iFindStart, bMatchCase);}int LastIndexOf(const T c, const int iFindStart = 0, bool bMatchCase = true) const{return _Math::strFindLast_t<T>(_pData, _nLength, &c, 1, iFindStart, bMatchCase);}/// <summary>/// 從某個位置開始查找一個單詞,這個單司是第一次出現,找到即返回,區分大小寫。/// </summary>/// <param name="sText"></param>/// <param name="sWord"></param>/// <param name="nFindStart"></param>/// <returns></returns>/// 創建時間: 2022-08-08      最后一次修改時間:2022-12-07  已測試(2022-12-07)int IndexOfWord(const _Str<T>& sWord, int iFindStart = 0, bool bMatchCase = true) const{if (_nLength == 0 || sWord._nLength == 0) return -1;  // 不加上這名,IndexWord("") 會進入死循環if (iFindStart <= 0) iFindStart = 0;if (_nLength - iFindStart < sWord._nLength) return -1;int nPos = IndexOf(sWord, iFindStart,bMatchCase);while (nPos != -1){bool bPrev = false;bool bNext = false;int nPrev = nPos - 1;int nNext = nPos + sWord._nLength;if (nPrev > 0){_char chPrev = _pData[nPrev];if (gs.s_Syntax_IsWordSeparator(chPrev)){bPrev = true;}}else{bPrev = true;}if (nNext > 0 && nNext < _nLength){_char chNext = _pData[nNext];if (gs.s_Syntax_IsWordSeparator(chNext)){bNext = true;}}else{bNext = true;}if (bNext && bPrev) return nPos;  //正確,是單詞//不正確,繼續查找nPos = IndexOf(sWord, nPos + sWord._nLength,bMatchCase);}return nPos;}/// <summary>/// 查找sFind第幾次出現的位置/// </summary>/// <param name="sFindString">查找內容</param>/// <param name="nCount">第幾個</param>/// <param name="iFindStart">開始位置</param>/// <param name="bMatchCase">是否大小寫匹配</param>/// <returns>找到返回第nCount次出現的位置,沒找到返回-1</returns>/// 創建時間:  2022-12-06      最后一次修改時間:2022-12-06   已測試(2022-12-06)int IndexOf_n(const _Str<T> &sFindString, const int nCount = 1, const int iFindStart = 0, bool bMatchCase = true) const{ 	assert(nCount >= 1);int n = 0;int iStart = iFindStart;int i = IndexOf(sFindString, iStart, bMatchCase);while (i != -1){++ n;iStart = i + sFindString._nLength;if (n == nCount) return i;	 i = IndexOf(sFindString, iStart, bMatchCase);}return i;}/// <summary>/// 截取字符串s1,s2中間的字符串,失敗返回空的字符串,s1為第一次出現的字符串。/// 注意: Intercept_First(s1,s2,false) = Intercept_First(s1,s2,0) /// </summary>/// <param name="s1"></param>/// <param name="s2"></param>/// <param name="nStart"></param>/// <param name="bMatchCase"></param>/// <returns></returns>/// 創建時間:  ????-??-??      最后一次修改時間:2022-12-06   已測試(2022-12-06)_Str<T> Intercept_First(const _Str<T>& s1, const _Str<T> &s2, const int iStart = 0, bool bMatchCase = true) const{int ipos1, ipos2;ipos1 = IndexOf(s1,iStart,bMatchCase);if (ipos1 == -1) return _t("");ipos2 = IndexOf(s2, ipos1 + s1._nLength,bMatchCase);if (ipos2 == -1){ return _t("");}else{  		return SubStr(ipos1 + s1._nLength, ipos2 - ipos1 - s1._nLength);}}/**示例:String^ str = "深圳市盈基實業有限公司國際通鄧事文*深圳市盈基實業有限公司國際通鄧事文";Label1.Text = str.LastIndexOf("鄧文").ToString();//返回-1Label1.Text = str.LastIndexOf("鄧").ToString();//返回32Label1.Text = str.LastIndexOf("鄧",8).ToString();//返回-1Label1.Text = str.LastIndexOf("鄧",20).ToString();//返回14Label1.Text = str.LastIndexOf("鄧",33).ToString();//返回32說明:在指定的范圍內查找字符,這個范圍是上面的輸入的參數,理解為,從索引0開始到指定的數值位置范圍內查找最后一個匹配的的字符串的位置。示例中,0-8中沒有“鄧”字,所以返回-1,0-20范圍中,有一個“鄧”字在索引14位置上,0-33范圍中有兩個“鄧”字,因為LastIndexOf是返回最后一個匹配項索引位置,所以返32,而不是14。*//// <summary>/// 截取字符串s1,s2中間的字符串,失敗返回空的字符串,s1,s2為均為最后一次出現的索引/// </summary>/// <param name="sText">字符串</param>/// <param name="s1">子串1</param>/// <param name="s2">子串2</param>/// <param name="bMatchCase">是否大小寫匹配</param>/// <returns></returns>/// 創建時間: ????-??-??     最后一次修改時間:2022-12-11  已測試inline _Str<T> Intercept_last(const _Str<T>& s1, const _Str<T>& s2,const int iStart = 0, bool bMatchCase = true){ int istart, iend;//算法: 要先查第二個字符串,然后從第二個字符串向前查找第一個字符串iend = LastIndexOf(s2, iStart, bMatchCase);if (iend == -1) return _t("");istart = LastIndexOf(s1, 0, iend - s2._nLength, bMatchCase);if (istart == -1)return _t("");int nInterceptLength = iend - istart - s1._nLength;int nStartIndex = istart + s1._nLength;return SubStr(nStartIndex, nInterceptLength);}/// <summary>/// 返回文件名///		_string s1 = _t("data");              =>           data/// 	_string s2 = _t("data.txt");          =>           data/// 	_string s3 = _t("c:\\data.txt");	  =>           data/// 	_string s4 = _t("data.txt.txt");      =>           data.txt/// </summary>/// <param name="sFullPathName"></param>/// <returns></returns> /// 創建時間: ????-??-??     最后一次修改時間:2022-12-11  已測試inline _Str<T> FileNameOnly()const{int iStart = LastIndexOf(_t('\\'));int iEnd = LastIndexOf(_t('.'));if (iStart == -1){if (iEnd != -1){if (iEnd  > 0)return SubStr(0, iEnd);}}else{if (iEnd != -1){if(iEnd - iStart - 1 > 0)return SubStr(iStart + 1, iEnd - iStart - 1);}}return *this;}/// <summary>/// 返回文件名,包括擴展名///		_string s1 = _t("data");              =>           data/// 	_string s2 = _t("data.txt");          =>           data.txt/// 	_string s3 = _t("c:\\data.txt");	  =>           data.txt/// 	_string s4 = _t("data.txt.txt");      =>           data.txt.txt/// </summary>/// <param name="sFullPathName"></param>/// <returns></returns>/// 創建時間: ????-??-??     最后一次修改時間:2022-12-11   已測試inline _Str<T> FileName() const{int iStart = LastIndexOf(_t('\\'));if (iStart != -1){if( _nLength - iStart - 1 > 0)return SubStr(iStart + 1, _nLength - iStart -1);}return *this;}/// <summary>/// Z:\Temp\迅雷下載\jtds-1.2.7-dist\CHANGELOG      //沒有文件擴展名的文件///		_string s1 = _t("data");              =>           /// 	_string s2 = _t("data.txt");          =>           txt/// 	_string s3 = _t("c:\\data.txt");	  =>           txt/// 	_string s4 = _t("data.txt.txt");      =>           txt/// </summary>/// <param name="sFileName">帶擴展名的文件名</param>/// <returns></returns>/// 獲取文件擴展名(創建時間:2014-06-13  最后一次修改時間:2020-01-11)  已測試inline _Str<T> FileNameExt()const{//Z:\Temp\迅雷下載\jtds-1.2.7-dist\CHANGELOG int n = LastIndexOf(_t("."));if (n != -1){if(_nLength - n - 1 > 0)return SubStr(n + 1, _nLength - n - 1);}return _t(""); }/// <summary>/// 返回文件夾目錄/// </summary>/// <returns></returns>inline _Str<T> FileDir()const{int n = LastIndexOf(_t("\\"));return n != -1 ? std_substr(0, n) : _t("");	 }/// <summary>/// 返回文件路徑,包括 反斜杠"\\",如果沒有,就返回空。/// C:\\data.txt   =>   C:\\/// </summary>/// <returns></returns>/// 創建時間: ????-??-??      最后一次修改時間:2022-12-11    已測試inline _Str<T> FileNamePath() const{int n = LastIndexOf(_t('\\'));return (n != -1 ? SubStr(0, n + 1) : _Str<T>());}/// <summary>/// 把路徑中的文件名用sNewName替代/// </summary>/// <param name="sNewFileName">新文件名</param>/// <returns></returns>/// 創建時間: ????-??-??      最后一次修改時間:2022-12-11    已測試inline  _Str<T> FileNameReplace(const _Str<T>& sNewFileName){//return FileNamePath() + sNewFileName + _t(".") + FileNameExt();_Str<T> sResult(_t(""), _nLength + sNewFileName._nLength);sResult.Add(FileNamePath());sResult.Add(sNewFileName);sResult.Add(_t('.'));sResult.Add(FileNameExt());return sResult;		}/// <summary>///C:\Program Files\Common Files\Oracle\Java\javapath\java.exe    返回 javapath///C:\Program Files\Common Files\Oracle\Java\javapath             返回 Java///C:\Program Files\Common Files\Oracle\Java\javapath\            返回 javapath///C:                                                             返回 C:/// 返回最后一個文件夾名/// </summary>/// <param name="sFullPathName"></param>/// <param name="IsDirectoryPath">此路徑是否文件夾名</param>/// <returns></returns>/// 創建時間: 2021-10-09      最后一次修改時間:2022-12-11  已測試inline _Str<T> FileDirectoryNameOnly(){int n1 = LastIndexOf(_t('\\'));if (n1 != -1){int n2 = LastIndexOf(_t('\\'), 0,n1 - 1);if (n2 != -1){ return SubStr(n2 + 1, n1 - n2 -1);}else{return SubStr(0, n1 - 1);}}return *this;}/// <summary>/// 把字符串翻轉/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: ????-??-??      最后一次修改時間:2022-12-11    已測試inline _Str<T>&  Reversal(){_Math::reverse<T>(_pData, _nLength);return *this;	 }/// <summary>/// 獲取以nIndex為中心的單詞或者詞語,以左邊光標為準。/// </summary>/// <param name="sText"></param>/// <param name="nMiddleIndex">中間字符在文本中的索引</param>/// <returns></returns>/// 創建時間:2022-12-12     最后一次修改時間:2022-12-12   (已測試)inline _Str<T> GetWord(int nMiddleIndex) const{if (_nLength == 0 || nMiddleIndex < 1 || nMiddleIndex >= _nLength)	return _t("");_char cLeft = _pData[nMiddleIndex - 1];_Str<T> sLeft(_t(""), 20);_Str<T> sRight(_t(""), 20);if(gs.c_IsChineseCharacter(cLeft))  //光標左邊的字符是英文{ 	for (int i = nMiddleIndex - 1; i >= 0; --i){_char c = _pData[i];if (gs.s_Syntax_IsWordSeparator(c)){break;}else{if (!gs.c_IsChineseCharacter(c)){break;}else{sLeft.Add(c);}}}for (int i = nMiddleIndex; i < _nLength; ++i){_char c = _pData[i];if (gs.s_Syntax_IsWordSeparator(c)){break;}else{if (!gs.c_IsChineseCharacter(c)){break;}else{sRight.Add(_pData[i]);}}}}else{for (int i = nMiddleIndex - 1; i >= 0; --i){_char c = _pData[i];if (gs.s_Syntax_IsWordSeparator(c)){break;}else{if (!gs.c_IsAscii(c)){break;}else{sLeft.Add(_pData[i]);}}}for (int i = nMiddleIndex; i < _nLength; ++i){_char c = _pData[i];if (gs.s_Syntax_IsWordSeparator(c)){break;}else{if (!gs.c_IsAscii(c)){break;}else{sRight.Add(_pData[i]);}}}}return sLeft.Reversal() + sRight;		 }/// <summary>/// 根據字符位置,返回行號,從0開始的索引。/// </summary>/// <param name="nPos"></param>/// <returns></returns>/// 創建時間:2022-12-21     最后一次修改時間: 2022-12-21   (已測試)inline int GetLineIndexForCharIndex(const int nPos)const{int nLineCount = 0;for (int i = 0; i <= nPos; ++i){if (_pData[i] == '\n'){++nLineCount;}}return nLineCount;}/// <summary>/// /// </summary>/// <param name="nPos"></param>/// <returns></returns>/// 創建時間:2022-12-28     最后一次修改時間: 2022-12-28    inline _Str<T> GetLineForCharIndex(const int nPos)const{ int j = nPos,k = nPos + 1;while (j > 0){if (_pData[j] == _t('\n')){break;}--j;}while (k < _nLength){if (_pData[k] == _t('\n')){break;}++k;}if ( k  < _nLength && k -j - 1 > 0){return SubStr(j + 1, k - j - 1);}else{return _t("");}}/// <summary>/// 是否郵件地址/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間:2022-01-20    最后一次修改時間:2022-01-20inline bool IsEmailAddress()const {	return gs.s_IsEmailAddress(_pData); 	}/// <summary>/// 判斷字符串是否全部是空格或者是控制字符。/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-03-01      最后一次修改時間:2022-03-01inline bool IsWhiteSpaceOrNotPrintable() const { return gs.s_IsWhiteSpaceOrNotPrintable(_pData); }/// <summary>/// 查找除空格以外第一次出現的可打印字符,sExcept字符除外。/// </summary>/// <param name="sText"></param>/// <param name="sExcept"></param>/// <returns></returns>/// 創建時間: 2022-03-01      最后一次修改時間:2022-03-01inline int FindFirstPrintable(const _char* sExcept = _t("")) const { return gs.s_FindFirstPrintable(_pData, sExcept); }/// <summary>/// 查找除空格以外最后一次出現的可打印字符,sExcept字符除外。/// </summary>/// <param name="sText">文本</param>/// <param name="sExcept">例外字符</param>/// <returns></returns>/// 創建時間: 2022-04-09      最后一次修改時間:2022-04-09inline int FindLastPrintable(const _char* sExcept = _t("")) const { return gs.s_FindLastPrintable(_pData, _nLength, sExcept); }/// <summary>/// 返回可打印的字符/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-02-07      最后一次修改時間:2022-02-07 inline _Str<T> PrintableCharacter()const{_Str<T> sResult(_t(""), _nLength);for (int i = 0; i < _nLength; ++i){_char c = _pData[i];if (gcf.gcf_isprint(c))sResult.Add(c);}return sResult;}/// <summary>/// 拷貝字符串前面的控制字符和空格,遇到其它可見字符馬上停止。/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-03-27      最后一次修改時間:2022-03-27inline _Str<T> CopyControlAndWhiteSpace()const{_Str<T> sResult(_t(""), _nLength);for (int i = 0; i < _nLength; ++i){_char c = _pData[i];if (gcf.gcf_IsControl(c) || gcf.gcf_isblank(c)){ sResult.Add(c);}else{break;}}return sResult; }/// <summary>/// 判斷是否序號標記,注意,最后一個字符必須是 "." 英文句號,注意,序號前面的空格和不可打印字符也會復制。/// 1. ab    返回:1.///    1. ab 返回:    1./// 序號定義:/// (1)如果句號不在最后,則句號后面一定是空格///  (2) 句號前面是連續的數字,且數字前面可以有空格或者不可打印字符///   /// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間:2022-03-06    最后一次修改時間:2022-10-03inline _Str<T> GetBook_序號標記()const{//1. //  1.//  11.//4.24 class aa// 1.2. 1. text   ok// int nPos = LastIndexOf(_t(". "));if (nPos != -1){_Str<T> sLeft = SubStr(0, nPos);bool bFind = false;for(_char c : sLeft){if ( gcf.gcf_isdigit(c) || gcf.gcf_isalpha(c) || gcf.gcf_IsControl(c) || gcf.gcf_isblank(c) || c == _t('.')){}else{bFind = true;}}if (!bFind){return sLeft + _t(". ");}}return GetBook_序號標記2();}/// <summary>///  (1)  或 (1)///  (2)  或 (2)/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間:2022-10-01    最后一次修改時間:2022-10-01inline _Str<T> GetBook_序號標記2()const{int nPos = IndexOf(_t(")"));  //英文括號if (nPos == -1)nPos = IndexOf(_t(")"));  //中文括號if (nPos == -1) return _t("");_Str<T> sSub = SubStr(0, nPos + 1);for(_char c : sSub){if (gcf.gcf_isdigit(c) || gcf.gcf_IsControl(c) || c == _t('(') || c == _t(')') || c == _t('(') || c == _t(')')){//如果要嚴謹一些,還要判斷括號是否配對}else{return _t("");}}return sSub + _t(" ");}/// <summary>///  格式  特殊符號 ch + 空格///  /// 	□ 為新的對象分配內存空間;/// 	□ 調用構造函數初始化對象的值/// 	□ 返回該對象的一個引用。/// </summary>/// <param name="sText"></param>/// <returns></returns>inline _Str<T> GetBook_特殊符號標記(const _Str<T>& sSpecificSymbol)const{int n = -1;for(_char c : sSpecificSymbol){n = IndexOf(c);if (n != -1){break;}}if (n == -1) return _t("");if (n + 1 >= _nLength) return _t("");if (_pData[n + 1] != _t(' ')) return  _t("");_Str<T> sSub = SubStr(0, n);if (sSub._nLength > 0){if ( !sSub.IsWhiteSpaceOrNotPrintable() ) return _t("");}else  //序號前面沒有字符{}return SubStr(0, n + 2);}/// <summary>/// 檢查字符串中是否有阿拉伯數字,如果有,返回直,否則返回假。/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: ????-??-??      最后一次修改時間:2023-31-19inline bool IsHaveArabicDigit()const{for (int i = 0; i < _nLength; ++i){if (gcf.gcf_isdigit(_pData[i])) return true;}return false;}/// <summary>/// 返回所有的數字/// </summary>/// <returns></returns>/// 創建時間: 2023-02-18      最后一次修改時間:2023-31-19inline _Str<T> GetAllArabicDigit()const{_Str<T> sResult;sResult.SetBuffer(_nLength);for (int i = 0; i < _nLength; ++i){T c = _pData[i];if (gcf.gcf_isdigit(c)){sResult.Add(c);}}return sResult;}/// <summary>/// 返回所有不可打印的字符串/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-01-21      最后一次修改時間:2022-12-13inline _Str<T> Unprintable()const{_Str<T> sResult(_t(""), _nLength);for (int i = 0; i < _nLength; ++i){_char c = _pData[i];if ( !gcf.gcf_isprint(c) ) sResult.Add(c);}return sResult; }/// <summary>/// 截取字符串前面的數字和小數點,遇到空格忽略,遇到小數點,數字,空格外的任何字停止截取。/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間:2021-12-27     最后一次修改時間:2021-12-27inline _Str<T> Intercept_Head_number_RadixPoint_Space()const{_Str<T> sResult(_t(""), _nLength);  for(int i = 0; i < _nLength; ++i){_char c = _pData[i];if (c == _t(' ')){}else if (c >= _t('0') && c <= _t('9')){sResult.Add(c);}else if (c == _t('.')){sResult.Add(_t('.'));}else{break;}}return sResult;}/// <summary>/// 返回: 如果nOrder=1,返回倒數第一位數字;如果nOrder=2,返回倒數第二位數字。/// </summary>/// <param name="sText"></param>/// <param name="nOrder"></param>/// <returns></returns>/// 創建時間:2021-12-27     最后一次修改時間:2021-12-27inline int LastNumberIndex(int nLastOrder = 1)const { return gs.s_LastNumberIndex(_pData, _nLength, nLastOrder); }/// <summary>/// 把字符串的最后第nOrder數字加1,如果最后第nOrder數字是9,則進一位,最后第nOrder+1數字再加1,如此循環,/// 但如果第nOrder+1找不到,則結束循環。/// </summary>/// <param name="sText"></param>/// <param name="nOrder">倒數第oOrder序列</param>/// <returns></returns>/// 創建時間:2021-12-27     最后一次修改時間:2022-03-06inline _Str<T> TryNumberAddOne(const int nLastOrder = 1)const{if (nLastOrder <= 0) return *this;_Str<T> sResult(_pData, 1);int i = LastNumberIndex(nLastOrder);if (i != -1){if (_pData[i] == _t('9')){sResult[i] = _t('0');//如果9前面有數字if (SubStr(0,i).IsHaveNumber())return sResult.TryNumberAddOne(nLastOrder + 1);else{					                  return  _t("1") + sResult;}}else{sResult[i] = (_char)( (int)_pData[i] + 1);return sResult;}}		 return sResult;}/// <summary>/// 把字符串的數字或者字母加一位,其它非數字或者字母忽略,例: a1 -> a2 , 1ab -> 1ac  19 -> 20, 99-> 100/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間:2022-09-11     最后一次修改時間:2022-09-11inline _Str<T> TryStrAndOne()const{		 if (_nLength == 0 ) return _t("1");int nLast = _nLength - 1;_char c = _pData[nLast];if (gcf.gcf_isdigit(c)){if (c != _t('9')){return SubStr(0, nLast).Add((_char)((int)c + 1));   // 1->2                 }else //進位,前面字符加1{return SubStr(0, nLast).TryStrAndOne().Add(_t("0"));}}else if (gcf.gcf_isalpha(c)){if (c != _t('z') && c != _t('Z') ){return SubStr(0, nLast).Add((_char)((int)c + 1));}else //進位,前面字符加1{if (c == _t('z'))return  SubStr(0, nLast).TryStrAndOne().Add(_t('a'));elsereturn SubStr(0, nLast).TryStrAndOne().Add(_t('Z'));}}else{return SubStr(0, nLast).TryStrAndOne().Add(c);} }/// <summary>/// 把字符串中的數字連起來,湊成整數,然后給這個數字減去1,再返回減去1的字符串。/// 例如: /// 1.3.9 小節 =>  1.3.8 小節/// 9.9.9 小節 =>  9.9.8 小節/// 0.0.0 小節 =>  9.9.9 小節/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-02-11      最后一次修改時間:2022-05-25inline _Str<T> TryNumberMinusOne(){_Str<T>  sResult(_pData, 1);bool bFind = false;_char* p = (_char*)sResult._pData;for (int i = sResult._nLength - 1; i >= 0; i--){if (p[i] >= _t('0') && p[i] <= _t('9') ){if (!bFind){if (p[i] != _t('0')){p[i] = (_char)((int)p[i] - 1);return sResult;}else{p[i] = _t('9');}bFind = true;}else{if (p[i] != _t('0')){p[i] = (_char)((int)p[i] - 1);return sResult;}else{p[i] = _t('9');}}}}return sResult;}/// <summary>/// 添加nCount個相同的字符sAppend。/// </summary>/// <param name="sText"></param>/// <param name="sAppend"></param>/// <param name="nCount"></param>/// <returns></returns>inline _Str<T>& AppendString(const _Str<T>& sAppend, int nCount){if (nCount > 0){SetBuffer(sAppend._nLength * nCount + _nDefaultBuffer);for (int i = 0; i < nCount; ++i){Add(sAppend);}}return *this;}/// <summary>/// 返回用cSplit隔開的字符串。/// </summary>/// <param name="sText"></param>/// <param name="cSplit"></param>/// <returns></returns>/// 創建時間: 2021-11-08      最后一次修改時間:2021-11-08inline _Str<T> SeparateWith(const _char cSplit) const{if (_nLength < 2) return *this;_Str<T> sResult(_t(""), _nLength * 2);for (int i = 0; i < _nLength - 1; ++i){sResult.Add(_pData[i]);sResult.Add(cSplit);}sResult.Add(_pData[_nLength - 1]);return sResult;}/// <summary>/// 所截取字符串的信息/// </summary>struct Intercept_info{/// <summary>/// 所截取的文本/// </summary>_Str<T> sIntercept = _t("");/// <summary>/// 第一個字符串開始出現的位置/// </summary>int iFindStart  = -1;/// <summary>/// 第二個字符串開始出現的位置/// </summary>int iFindEnd = -1;/// <summary>/// 所截取的文本字符串開始處/// </summary>int iTextStart = -1;/// <summary>/// 所截擊的文本結束處/// </summary>int iTextEnd = -1;};/// <summary>/// 截取字符串s1,s2中間的字符串,失敗返回空的字符串。/// </summary>/// <param name="s1">第一次出現的字符串s1</param>/// <param name="s2">第一次出現的字符串s2</param>/// <param name="iStart">開始位置</param>/// <param name="bMatchCase">是否區大小寫</param>/// <returns>如果成功,返回所截取的字符串,否則返回空</returns>/// 創建時間: ????-????-????      最后一次修改時間:2022-08-26Intercept_info Intercept(const _Str<T>& s1, const _Str<T>& s2, const int iStart = 0, bool bMatchCase = true) const{Intercept_info iInfo;iInfo.iFindStart = -1;iInfo.iFindEnd = -1;iInfo.iTextStart = -1;iInfo.iTextEnd = -1;iInfo.sIntercept = _t("");iInfo.iFindStart = IndexOf(s1, iStart, bMatchCase);if (iInfo.iFindStart == -1){return iInfo;}iInfo.iFindEnd = IndexOf(s2, iInfo.iFindStart + s1._nLength, bMatchCase);if (iInfo.iFindEnd != -1){		 iInfo.iTextStart = iInfo.iFindStart + s1._nLength;iInfo.iTextEnd = iInfo.iFindEnd - s2._nLength - 1;iInfo.sIntercept = SubStr(iInfo.iFindStart + s1._nLength, iInfo.iFindEnd - iInfo.iFindStart - s1._nLength);}return iInfo;}/// <summary>/// 檢查字符串是否全都是阿拉伯數字,如果是,則返回真,否則返回假。/// </summary>/// <returns>如查全是數字,返回真</returns>inline bool IsAllArabicDigitString() const{if( _nLength == 0) return false;for (int i = 0; i < _nLength; ++i){_char c = _pData[i];if (c < _t('0') || c > _t('9')) return false;}return true;  }/// <summary>/// 檢查字符串是否數字/// </summary>/// <returns></returns>/// 創建時間: 2023-05-22     最后一次修改時間:2023-05-22inline bool IsNumber() const{if (_nLength == 0) return false;int n = StrCount(_t('.'));if (n > 1) return false;if (n == 0){int iStart = 0;if (_pData[0] == _t('-') || _pData[0] == _t('+')){iStart = 1;}for (int i = iStart; i < _nLength; ++i){_char c = _pData[i];if (c < _t('0') || c > _t('9')) return false;}}else{int iStart = 0;if (_pData[0] == _t('-') || _pData[0] == _t('+')){iStart = 1;}for (int i = iStart; i < _nLength; ++i){_char c = _pData[i];if (c != _t('.')){if (c < _t('0') || c > _t('9')) return false;}}				}return true;}/// <summary>/// 是否整數字符串/// </summary>/// <returns></returns>/// 創建時間: 2023-05-22     最后一次修改時間:2023-05-22inline bool IsIntNumber() const{if (_nLength == 0) return false;int iStart = 0;if (_pData[0] == _t('-') || _pData[0] == _t('+')){iStart = 1;}for (int i = iStart; i < _nLength; ++i){_char c = _pData[i];if (c < _t('0') || c > _t('9')) return false;}return true;}/// <summary>/// 是否浮點數字符串/// </summary>/// <returns></returns>/// 創建時間: 2023-05-22     最后一次修改時間:2023-05-22inline bool IsDoubleNumber() const{if (_nLength == 0) return false;int n = StrCount(_t('.'));if (n != 1) return false;int iStart = 0;if (_pData[0] == _t('-') || _pData[0] == _t('+')){iStart = 1;}for (int i = iStart; i < _nLength; ++i){_char c = _pData[i];if (c != _t('.')){if (c < _t('0') || c > _t('9')) return false;}}return true;		 }/// <summary>/// 檢查字符串是否數字,包括中文大寫數字和中文小寫數字/// </summary>/// 創建時間: 2023-03-19      最后一次修改時間:2023-03-19  已測試(2023-03-19)inline bool IsNumberString()const{bool bOk = true;for (int i = 0; i < _nLength; ++i){if (!gs.c_IsChineseLowerCaseDigit(_pData[i])){bOk = false;break;}}if (bOk) return true;  //全是中文小寫bOk = true;for (int i = 0; i < _nLength; ++i){if (!gs.c_IsChineseUpperCaseDigit(_pData[i])){bOk = false;break;}}if (bOk) return true;  //全是中文d大寫bOk = true;for (int i = 0; i < _nLength; ++i){if (!gs.c_IsArabicDigit(_pData[i])){bOk = false;break;}}if (bOk) return true;  //全是阿們伯數字return false;}/// <summary>/// 在sText中的字符是否都能在CharElementsCollection中找到,如果是,返回真。/// </summary>/// <param name="sText"></param>/// <param name="CharElementsCollection"></param>/// <returns></returns>/// 創建時間: 2022-04-06      最后一次修改時間:2022-12-07  已測試(2022-12-06)inline bool IsElementsCollection(const _char *CharElementsCollection, bool bMatchCase = true) const{if (CharElementsCollection == null) return false;_char* p = (_char*)CharElementsCollection;		int i = -1;while (*p){i = IndexOf(*p,0,bMatchCase);if (i == -1) return false;++p;}return i != -1;}/// <summary>/// 是否全是控制字符/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-09-17      最后一次修改時間:2022-09-17 inline  bool IsAllControl() const{if (_nLength == 0) return false;for(int i = 0; i < _nLength; ++i){if (!gcf.gcf_iscntrl(_pData[i])) return false;}return true;}/// <summary>/// 檢查是否存在任何字符/// </summary>/// <param name="sAny"></param>/// <returns></returns>/// 創建時間: 2022-12-30      最后一次修改時間:2022-12-30 inline bool IsHaveAnyChar(const _char* sAny)const{_char* p = (_char*)sAny;while (*p){if (IndexOf(*p) != -1){return true;}++p;}return false;}/// <summary>/// 檢查是否有中文字符/// </summary>/// <returns></returns>/// 創建時間: 2023-02-08      最后一次修改時間:2023-02-08inline bool IsHaveChineseCharacter()const{for (int i = 0; i < _nLength; ++i){if (gs.c_IsChineseCharacter(_pData[i])){return true;}}return false;}/// <summary>/// 是否錯誤的文件名/// </summary>/// <returns></returns>/// 創建時間: 2022-12-30      最后一次修改時間:2022-12-30 bool IsInvalidPathName()const{return ( IsHaveAnyChar(gs.InvalidPathChars) || _nLength > 260 );}/// <summary>/// 是否全是小寫英文字母/// </summary>/// <returns></returns>/// 創建時間: 2022-12-20      最后一次修改時間:2022-12-20inline bool IsAllLowerCaseEnglishLetter()const{if (_nLength == 0) return false;for (int i = 0; i < _nLength; ++i){if (  _pData[i] < _t('a') ||  _pData[i] > _t('z')  ) return false;}return true;}/// <summary>/// 返回所有的控制字符的拷貝/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-09-17      最后一次修改時間:2022-09-17 inline _Str<T> CopyControl() const{_Str<T> sResult(_t(""), _nLength);for (int i = 0; i < _nLength; ++i){if (gcf.gcf_iscntrl(_pData[i])) sResult.Add(_pData[i]);}return sResult;}/// <summary>/// 返回不包含空格和控制字符的可打印字符/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2022-02-07      最后一次修改時間:2022-02-07 inline _Str<T> RemoveWCPrintable() const{_Str<T> sResult(_t(""), _nLength);for (int i = 0; i < _nLength; ++i){if ( gcf.gcf_isprint(_pData[i]) && (!gcf.gcf_iscntrl(_pData[i])) && (!gcf.gcf_isspace(_pData[i])) ){sResult.Add(_pData[i]);}} return sResult;}/// <summary>/// 返回每一個字符都用cSplit隔開的字符串。/// </summary>/// <param name="cSplit">分隔符</param>/// <returns></returns>/// 創建時間: 2021-11-08      最后一次修改時間:2022-12-08inline _Str<T> ConnectForSplit(const _char cSplit) const{if (_nLength <= 1) return *this;_Str<T> sResult(_t(""), _nLength * 2);for (int i = 0; i < _nLength - 1; ++i){sResult.Add(_pData[i]);sResult.Add(cSplit);}sResult.Add(last());return sResult;}/// <summary>/// 返回每一個字符都用sSplit隔開的字符串的拷貝/// </summary>/// <param name="cSplit">分隔符</param>/// <returns></returns>/// 創建時間: 2021-11-08      最后一次修改時間:2022-12-08inline _Str<T> ConnectForSplit(const _char *sSplit) const{assert(sSplit != null && *sSplit != 0);if (_nLength <= 1) return *this;int n = _Math::strLen_t<T>(sSplit);_Str<T> sResult(_t(""), _nLength + _nLength * n);for (int i = 0; i < _nLength - 1; ++i){sResult.Add(_pData[i]);sResult.Add(sSplit,n);}sResult.Add(last());return sResult;}/// <summary>/// 返回每隔nCount個字符以cSplitChar分隔的字符串的拷貝/// </summary>/// <param name="cSplitChar">分隔字符</param>/// <param name="nCount"></param>/// <returns></returns>/// 創建時間: 2023-02-25      最后一次修改時間:2023-02-25inline _Str<T> ConnectForSplit(const T cSplitChar, const int nCount) const{assert(cSplitChar != 0 && nCount > 0);_Str<T> sResult(_t(""), _nLength * 2);for (int i = 0; i < _nLength; ++i){sResult.Add(_pData[i]);if ( (i + 1) % nCount == 0){if( i + 1 != _nLength)sResult.Add(cSplitChar);}}return sResult;}/// <summary>/// 返回用charArray中的每一個字符分割的數組/// </summary>/// <param name="charArray"></param>/// <returns></returns>/// 創建時間: 2023-05-13      最后一次修改時間:2023-05-13 (已測試)inline _Array<_Str<T>> SplitEveryChar(const T* charArray, bool bIgnoreEmptyString = false)const{_Array<_Str<T>> arrResult;_Str<T> tmp;for (int i = 0; i < _nLength; ++i){		if (_Math::strChr_t<T>(charArray, _pData[i]) == -1){tmp.Add(_pData[i]);}else{if (tmp.Length == 0){if (!bIgnoreEmptyString){arrResult.Add(tmp);}}else{arrResult.Add(tmp);}tmp.Clear();}} if (_nLength > 0)  //添加最后一個{if (tmp.Length == 0){if (!bIgnoreEmptyString){arrResult.Add(tmp);}}else{arrResult.Add(tmp);}}return arrResult;		}/// <summary>/// 返回除ASCII以外的的字符。/// </summary>/// <param name="sText"></param>/// <returns></returns>/// 創建時間: 2021-12-25      最后一次修改時間:2021-12-25inline _Str<T> RemoveASCII() const{if (_nLength <= 1) return *this;_Str<T> sResult(_t(""), _nLength);for (int i = 0; i < _nLength; ++i){if(!gcf.gcf_isascii(_pData[i]))	sResult.Add(_pData[i]);			}return sResult;}/// <summary>/// 返回除去 nStart 到 nEnd 的一段,包括 nStart 和 nEnd 字符的拷貝,原字符串不變。/// </summary>/// <param name="nStart"></param>/// <param name="nEnd"></param>/// <returns></returns>/// 創建時間: 2023-02-15      最后一次修改時間:2023-02-15 (已測試)inline _Str<T> Remove(const int nStart, const int nEnd) const{assert(nStart >= 0 && nEnd >= 0 && nEnd >= nStart);_Str<T> sResult;sResult.SetBuffer(_nLength);//拷貝前半部分sResult.Add(_pData, nStart);//拷貝后半部分sResult.Add(_pData + nEnd + 1, _nLength - nEnd - 1);return sResult;}/// <summary>/// 近回把字符串區間 [nReplaceStart ,nReplaceEnd] 用 sNewString 代替的拷貝,原字符串不變。/// </summary>/// <param name="nReplaceStart"></param>/// <param name="nReplaceEnd"></param>/// <param name="sNewString"></param>/// <returns></returns>/// 創建時間: 2023-02-21      最后一次修改時間:2023-02-21 (已測試)inline _Str<T> Replace(const int nReplaceStart, const int nReplaceEnd, const _Str<T>& sNewString){assert(nReplaceStart >= 0 && nReplaceEnd >= 0 && nReplaceEnd >= nReplaceStart && nReplaceStart < _nLength &&nReplaceEnd < _nLength);_Str<T> sResult;sResult.SetBuffer(_nLength + sNewString._nLength);int n = 0;//拷貝前半部分sResult.Add(_pData, nReplaceStart);sResult.Add(sNewString);//拷貝后半部分sResult.Add(_pData + nReplaceEnd + 1, _nLength - nReplaceEnd - 1);return sResult;}/// <summary>/// 返回一個把舊的字符串用新的字符串代替的拷貝。/// </summary>/// <param name="sOld"></param>/// <param name="sNewStr"></param>/// <returns></returns>/// 創建時間: 2023-05-10      最后一次修改時間:2023-05-11 (已測試)inline _Str<T> ReplaceAll(const _Str<T>& sOld, const _Str<T>& sNew)const{if (sOld.Length == 0) return *this; //返回拷貝int i = this->IndexOf(sOld);if( i == -1) return *this; //返回拷貝_Str<T> sResult(_t(""), _nLength);int j = 0;while (i != -1){ sResult.Add(SubStr(j, i - j));sResult.Add(sNew);j = i + sOld.Length;i = IndexOf(sOld, j);		}//拷貝最后一段if (j < _nLength){sResult.Add(SubStr(j, _nLength - j));}return sResult;}/// <summary>/// 返回一個把舊的字符串用新的字符串代替的拷貝。/// </summary>/// <param name="arrOld"></param>/// <param name="arrNew"></param>/// <returns></returns>/// 創建時間: 2023-05-11      最后一次修改時間:2023-05-11 (已測試)inline _Str<T> ReplaceAll(const _Array<_Str<T>>& arrOld, const const _Array<_Str<T>>& arrNew)const{assert(arrOld.Length == arrNew.Length);_string sResult = *this;for (int i = 0; i < arrOld.Length; ++i){sResult = sResult.ReplaceAll(arrOld[i], arrNew[i]);}return sResult;}/// <summary>/// 返回不包含sCharArray的所有字符的文本的拷貝/// </summary>/// <param name="sText"></param>/// <param name="sCharArray"></param>/// <returns></returns>/// 創建時間: 2021-12-25      最后一次修改時間:2021-12-25inline _Str<T> RemoveCharArray(const T* pCharArray)const{_Str<T> sResult((T*)null, _nLength);for (int i = 0; i < _nLength; ++i) {if (_Math::strChr_t<T>(pCharArray, _pData[i]) == -1) {sResult.Add(_pData[i]);}}return sResult;}/// <summary>/// 返回除去tChar的字符串/// </summary>/// <param name="tChar"></param>/// <returns></returns>/// 創建時間: 2023-05-04      最后一次修改時間:2023-05-04inline _Str<T> RemoveChar(const T& tChar)const{_Str<T> sResult((T*)null, _nLength);for (int i = 0; i < _nLength; ++i) {if(_pData[i] != tChar)sResult.Add(_pData[i]);}return sResult;}/// <summary>/// 每隔nCount字符用分隔符cSplit進行分組。 /// </summary>/// <param name="sText"></param>/// <param name="nCount"></param>/// <param name="cSplit"></param>/// <returns></returns>/// 創建時間: 2021-11-13      最后一次修改時間:2022-12-08inline _Str<T> DivideIntoGroups(const int nCount, const _char cSplit) const {assert(cSplit != 0);int n = _nLength / nCount;if (n <= 1)	return *this;_Str<T> sResult(null, _nLength + nCount * 2);for (int i = 0; i < n - 1; ++i){sResult.Add(SubStr(nCount * i, nCount));sResult.Add(cSplit);}//拷貝剩下的sResult.Add(SubStr(nCount * (n - 1), _nLength - nCount * (n - 1)));return sResult;}/// <summary>/// 放棄對象當前使用的內存,可能內存已托管給別的對象,/// 重新初始化當前對象,除非內存給其它對象托管,否則不要調用這個函數。/// </summary>/// 創建時間:2022-12-29    最后一次修改時間:2022-12-29inline void GiveUpMem(){this->InitData(0);}/// <summary>/// 托管其他對象的內存,在 pData中,要有一個以零為值的 T 數據。/// </summary>/// <param name="pMemory"></param>/// <param name="nCount"></param>/// 創建時間:2022-12-29    最后一次修改時間:2022-12-29inline virtual void TrusteeshipMem(const _byte* pData, const int& nMemoryLength){ClearMemory();  //清除內存int nCount = nMemoryLength / sizeof(T);if (nCount * sizeof(T) != nMemoryLength){			throw _t("托管內存錯誤!");}_pData = (T*)pData;	_nLength = _Math::strLen_t<T>(_pData);_nBuffer = nCount - _nLength - 1;if (_nBuffer < 0){throw _t("托管內存錯誤!");}}//_Check_return_                    _ACRTIMP double    __cdecl atof(_In_z_ char const* _Str<T>ing);//_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int       __cdecl atoi(_In_z_ char const* _Str<T>ing);//_Check_return_                    _ACRTIMP long      __cdecl atol(_In_z_ char const* _Str<T>ing);//_Check_return_                    _ACRTIMP long long __cdecl atoll(_In_z_ char const* _Str<T>ing);//_Check_return_                    _ACRTIMP __int64   __cdecl _atoi64(_In_z_ char const* _Str<T>ing);inline __int64 ToInt64()const{//return ::_atoi64( (_char*)_pData);return std::stoll((_char*)_pData);}inline int ToInt()const { //return ::atoi((_char*)_pData);return std::stoi((_char*)_pData);}inline int ToDouble()const {//return ::atof((_char*)_pData); return std::wcstod((_char*)_pData);}/// <summary>/// 比較字符串大小/// </summary>/// <param name="s"></param>/// <returns></returns>/// 創建時間:2023-01-18    最后一次修改時間:2023-01-18inline int CompareTo(const  _Str<T>& s)const{return _Math::StrCmp_t<T>(_pData, s._pData);}/// <summary>/// 把每個字符都用UNICODE值表示,且每人字符都用逗號分隔。/// </summary>/// <returns></returns>/// 創建時間:2023-06-27    最后一次修改時間:2023-06-27  (已測試)inline _Str<T> UnicodeVale()const{_Str<T> result;if (_nLength <= 0) return result;result.SetBuffer(_nLength * 4);if ( typeid(_char) == typeid(T) ){for (int i = 0; i < _nLength - 2; ++i){result.Add(  _Math::IntToStr((__int64)_pData[i]).Data);result.Add((const T*)",");}result.Add(_Math::IntToStr((__int64)_pData[_nLength - 1]).Data);}	 return result;}/// <summary>/// 把緩沖區初始化為0/// </summary>/// 創建時間:2023-02-08    最后一次修改時間:2023-02-08inline void ZeroBuffer(){ for (int i = _nLength + 1; i <=  _nBuffer + _nLength; ++i){ _pData[i] = 0;}}//---------------------------------------------------------------------------------------靜態函數inline static _Str<wchar_t> CopyFrom(const wchar_t* pStr, const int nCopyCount){ _Str<wchar_t> sResult(L"", nCopyCount);/*sResult.setlfor (int i = 0; i < nCopyCount; ++i){sResult.Add(pStr[i]); }*/_Memory::Copy<wchar_t>((wchar_t*)sResult.Data, pStr, nCopyCount);sResult.SetNewLength(nCopyCount);return sResult;}inline static _Str<char> CopyFrom(const char* pStr, const int nCopyCount){_Str<char> sResult("", nCopyCount);/*for (int i = 0; i < nCopyCount; ++i){sResult.Add(pStr[i]);}*/_Memory::Copy<char>((char*)sResult.Data, pStr, nCopyCount);sResult.SetNewLength(nCopyCount);return sResult;}};//----------------------------------------------------------------------------------------#ifdef _UNICODE_template<class T>
std::wistream& operator >> (std::wistream& os, _Str<T>& aString)
{_Mem<T> m(1000);os >> m.Pointer;aString = m.Pointer;return os;
}template<class T>
std::wostream& operator<<(std::wostream& os, const _Str<T>& aString)
{os << aString.Data;return os;
}#else
template<class T>
std::istream& operator >> (std::istream& os, _Str<T>& aString)
{_Mem<T> m(1000);os >> m.Pointer;aString = m.Pointer;return os;
}template<class T>
std::ostream& operator<<(std::ostream& os, const _Str<T>& aString)
{os << aString.Data;return os;
}#endif_LF_END_#endif 

_StrW.h

/*******************************************************************************************
文件名			: _StrW.h作者				: 李鋒功能				: UNICODE 字符串創建時間			: 2023年2月13日最后一次修改時間	:  2024年24月13日********************************************************************************************/
#ifndef __STRW_H_
#define __STRW_H_#include "_Str.h"#ifdef _MFC_#include<afx.h>
#endif//#include "C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.8/mscorlib.dll"_LF_BEGIN_class _StrListW; /// 前置聲明
class _StrA;class _StrW : public _Str<wchar_t>
{
public://---------------------------------------------------------------------------------構造與析構/// <summary>/// 缺省構造,默認為15個字符的緩沖大小/// </summary>_StrW() : _Str<wchar_t>() {}_StrW(const _StrW& rhs) : _Str<wchar_t>(rhs) {}_StrW(const _Str<wchar_t>& rhs) : _Str<wchar_t>(rhs) {}/// <summary>///  拷貝構造,默認為0個字符的缺省緩沖/// </summary>/// <param name="pStr"></param>/// <param name="nBuffer">緩沖區個數</param>/// <param name="bZeroBuffer">是否實始化 buffer</param>/// 創建時間: ????-??-??      最后一次修改時間:2023-02-08_StrW(const wchar_t* pStr, const int& nBuffer = 0, bool bZeroBuffer = false): _Str<wchar_t>(pStr, nBuffer, bZeroBuffer) {}#ifdef _STR_COMPATIBILITY_/// <summary>/// 允許 _StrW  str("abc");  而不是每次都要寫 _StrW str(_t("abc"))/// </summary>/// <param name="pStr">數據指針</param>/// <param name="nBuffer">緩沖大小</param>/// <param name="bZeroBuffer">是否把緩沖初始化為零</param>/// 創建時間: 2023-05-08    最后一次修改時間:2023-05-08 _StrW(const char* pStr, const int& nBuffer = 0, bool bZeroBuffer = false);operator _StrA() const;#endif/// <summary>/// 拷貝構造函數/// </summary>/// <param name="pstr">要拷貝的字符串</param>/// <param name="nStrLength">要拷貝的字符串長度</param>/// <param name="nCopyStart">從那里開始拷貝,索引從零開始</param>/// <param name="nCopyLength">要拷貝的長度</param>/// <param name="nBuffer">字符串區緩沖區長度</param>/// 創建時間: ????-??-??      最后一次修改時間:2021-11-02explicit _StrW(const wchar_t* pstr, const int& nStrLength, const int& nCopyStart, const int& nCopyLength, const int& nBuffer = 0): _Str<wchar_t>(pstr, nStrLength, nCopyStart, nCopyLength, nBuffer) {}//inline _StrW(const std::wstring& sText) : _Str<wchar_t>(sText) {}inline _StrW(const std::wstring& sText){InitData( (int) sText.length() + _nDefaultBuffer);Add(sText.c_str(), (int)sText.length());} inline explicit _StrW(const size_t& nLength, const wchar_t& ch) : _Str<wchar_t>(nLength, ch) {}/// <summary>/// 轉換為單字節字符串/// </summary>/// <returns></returns>_StrA ToStrA()const;#ifdef  _CLR_  /// <summary>/// /// </summary>/// <param name="sText"></param>/// <param name="nBuffer"></param>/// <param name="bZeroBuffer"></param>/// 創建時間: ????-??-??      最后一次修改時間:2022-02-08inline _StrW(String^ sText, const int& nBuffer = 0, bool bZeroBuffer = false) : _Str<wchar_t>(sText, nBuffer, bZeroBuffer) {} inline  operator String ^ () const { return gcnew String(_pData); }#endif#ifdef _MFC_/// <summary>/// /// </summary>/// <param name="sText"></param>/// <param name="nBuffer"></param>/// <param name="bZeroBuffer"></param>/// 創建時間: 2024-01-22      最后一次修改時間:2024-01-22inline _StrW(const CString& sText, const int& nBuffer = 0, bool bZeroBuffer = false) : _Str<wchar_t>((const wchar_t*)sText, nBuffer, bZeroBuffer) {}/// <summary>/// /// </summary>/// 創建時間: 2024-01-22      最后一次修改時間:2024-01-22inline  operator CString () const { return CString(_pData); } 
#endif//--------------------------------------------------------------------------------------------------------------------------類型轉換/// <summary>/// 強制類型轉換  char_ *p = (char_ *) this;/// 或在函數調用中參數類型為 const char_ *p 時 ,而當你傳入的類型為 str_時,編譯器自動會把 str_ 類型轉換為 str_._pData ;/// </summary>inline operator const wchar_t* () const { return _pData; }//--------------------------------------------------------------------------------------------------------------Java String//--------------------------------------------------------------------------------------------------------------CSharp String//--------------------------------------------------------------------------------------------------------------Python String/// <summary>/// 返回全是大寫字母的拷貝/// </summary>/// <returns></returns>/// 創建時間: 2023-03-25      最后一次修改時間:2023-03-25 _StrW Python_upper()const { return Upper(); }/// <summary>/// 返回全是小寫字母的持由/// </summary>/// <returns></returns>/// 創建時間: 2023-03-25      最后一次修改時間:2023-03-25 _StrW Python_lower()const { return Lower(); }/// <summary>/// 模擬Python String.format/// </summary>/// <param name="pArgList"></param>/// <returns></returns>/// 創建時間: 2023-03-26      最后一次修改時間:2023-03-26 (已測試)_StrW Python_format(const _StrListW& pArgList)const;/// <summary>/// 模擬Python String.format/// </summary>/// <param name="sArg"></param>/// <param name="sSplit"></param>/// <returns></returns>/// 創建時間: 2023-03-26      最后一次修改時間:2023-03-26 (已測試)_StrW Python_format(const _StrW& sArg, const _StrW& sSplit)const;/// <summary>/// 參數為null時刪除左邊的空白字符(包括’\n’, ‘\r’, ‘\t’, ’ ')/// </summary>/// <returns></returns>/// 創建時間: 2023-03-28      最后一次修改時間:2023-03-28 (已測試)_StrW Python_lstrip(const wchar_t* pArrayChar = null)const;/// <summary>/// 參數為null時刪除右邊的空白字符(包括’\n’, ‘\r’, ‘\t’, ’ ')/// </summary>/// <param name="pArrayChar"></param>/// <returns></returns>/// 創建時間: 2023-03-28      最后一次修改時間:2023-03-28  (已測試)_StrW Python_rstrip(const wchar_t* pArrayChar = null)const;/// <summary>/// 默認刪除兩邊的空白符(包括’\n’, ‘\r’, ‘\t’, ’ '),注意:只刪除開頭或是結尾的字符,不刪除中間部分的字符。/// </summary>/// <returns></returns>/// 創建時間: 2023-03-28      最后一次修改時間:2023-03-28  (已測試)_StrW Python_strip(const wchar_t* pArrayChar = null)const;bool FileExists()const;bool FileDelete() const;/// <summary>/// 查找第一次出現的子串,且子串后面的字符按一定的規則排列,: 第一種字符是 CharType1, 第二種是 CharType2 類型 ,依次類推./// 例 : ///      _Array<_CharType> ctArray = { _CharType::Digit,_CharType::EnglishLetters, _CharType::WhiteSpace };///		_StrA  s = "s1s1s s1a S2a W";///     _pcn(s3.PowerIndexOf("s", ctArray));              結果是 2,5/// 	_pcn(s3.PowerIndexOf("s", ctArray, 10));          結果是 -1,-1/// 	_pcn(s3.PowerIndexOf("s", ctArray, 10, false));   結果是 10,13/// </summary>/// <param name="sPartOne">第一部分字符</param>/// <param name="ctArrayOtherPart">其它部分字符規則</param>/// <param name="nPosStart">查找開始的位置</param>/// <param name="bMatchCase">是否大小寫匹配</param>/// <returns>找到返回第一個字符的位置和最后一個字符的位置</returns>/// 創建時間:  2022-02-20      最后一次修改時間:2022-02-21   已測試(2023-02-21)_Pair<int, int> PowerIndexOf(const _StrW& sPartOne, const _Array<_CharType> ctArrayOtherPart, const int nPosStart = 0, bool bMatchCase = true);/// <summary>/// 以nMiddleIndex為中心,獲取一個Word的左右邊界,邊界以空格或者特殊符號或者控制字符為界限。/// </summary>/// <param name="nMiddleIndex">中間字符在文本中的索引</param>/// <returns></returns>/// 創建時間:2022-12-17     最后一次修改時間: 2022-12-17   (已測試)_Pair<int, int> GetWordBorder(int nMiddleIndex) const;/// <summary>/// /// </summary>/// <param name="ctRule"></param>/// <returns></returns>/// 創建時間: 2023-02-26      最后一次修改時間:2023-02-26bool IsMatchRule(const _Array<_CharType>& ctRule);};_LF_END_#endif

_StrW.cpp

#include "_StrW.h"
#include "_StrA.h"
#include "_StrListW.h"#include "_Array.h"
#include "_Pair.h"_LF_BEGIN__StrW _StrW::Python_format(const _StrListW& pArgList) const
{_StrW sResult;//設置緩沖區sResult.SetBuffer(_nLength + pArgList.GetStringLength());int iCount = 0;for (int i = 0; i < _nLength; ++i){if (_pData[i] == L'{'){//查找第二個配對int iEnd = this->IndexOfRightPairChar(i, L'{', L'}');if (iEnd != -1){//獲取 {  }  中的數字字符_StrW sCount = SubStr(i, iEnd - i).GetAllArabicDigit();if (sCount.Length == 0)   //自動選擇參數{ if (iCount < pArgList.Count){sResult.Add(pArgList[iCount]);} else{sResult.Add(L"{ NULL }");}++iCount; //參數計數             }else{int n = _Math::strToInt_t<wchar_t>(sCount.Data); //指定參數if (n < pArgList.Count){sResult.Add(pArgList[n]);}else{sResult.Add(L"{ NULL }");}}i = iEnd;  //跳過 {??}  參數}}else{sResult.Add(_pData[i]);}}return sResult;
}_StrW _StrW::Python_format(const _StrW& sArg, const _StrW& sSplit) const
{return Python_format(_StrListW(sArg, sSplit,true));
}_StrW _StrW::Python_lstrip(const wchar_t* pArrayChar) const
{     int nLelfCopyStart = _nLength; //左邊開始拷貝位置const wchar_t* pRemove = pArrayChar == null ? L"\t\n\r " : pArrayChar;for (int i = 0; i < _nLength; ++i){       if (_Math::strChr_t<wchar_t>(pRemove, _pData[i]) == -1){           nLelfCopyStart = i;break;     }     }  return nLelfCopyStart < _nLength ? SubStr(nLelfCopyStart, _nLength - nLelfCopyStart) : _StrW();
}_StrW _StrW::Python_rstrip(const wchar_t* pArrayChar) const
{int nRightCopyStart = -1; //右邊開始拷貝位置const wchar_t* pRemove = pArrayChar == null ? L"\t\n\r " : pArrayChar;for (int i = _nLength - 1; i >= 0; --i){if (_Math::strChr_t<wchar_t>(pRemove, _pData[i]) == -1){nRightCopyStart = i;break;}}return nRightCopyStart > 0 ? SubStr(0, nRightCopyStart + 1) : _StrW();
}_StrW _StrW::Python_strip(const wchar_t* pArrayChar) const
{int nLelfCopyStart = _nLength; //左邊開始拷貝位置const wchar_t* pRemove = pArrayChar == null ? L"\t\n\r " : pArrayChar;for (int i = 0; i < _nLength; ++i){if (_Math::strChr_t<wchar_t>(pRemove, _pData[i]) == -1){nLelfCopyStart = i;break;}}int nRightCopyStart = -1; //右邊開始拷貝位置for (int i = _nLength - 1; i >= 0; --i){if (_Math::strChr_t<wchar_t>(pRemove, _pData[i]) == -1){nRightCopyStart = i;break;}}//拷貝長度int nCopyLength = nRightCopyStart - nLelfCopyStart + 1;return nCopyLength > 0 ? SubStr(nLelfCopyStart, nCopyLength) : _StrW();
}bool _StrW::FileExists() const
{return gcf.gcf_FileExisits(_pData); 
}bool _StrW::FileDelete() const
{ return  gcf.gcf_FileDelete(_pData);  
}_Pair<int, int> _StrW::GetWordBorder(int nMiddleIndex) const{_Pair<int, int> pResult;pResult.First = 0;pResult.Second = 0;for (int i = nMiddleIndex; i >= 0; --i){_char c = _pData[i];if (gs.s_Syntax_IsWordSeparator(c)){pResult.First = i + 1;break;}}for (int i = nMiddleIndex + 1; i < _nLength; ++i){_char c = _pData[i];if (gs.s_Syntax_IsWordSeparator(c)){pResult.Second = i - 1;break;}}return pResult;
}bool _StrW::IsMatchRule(const _Array<_CharType>& ctRule)
{if (ctRule.Length == 0){return true;}return true;
}_Pair<int, int> _StrW::PowerIndexOf(const _StrW& sPartOne, const _Array<_CharType> ctArrayOtherPart, const int nPosStart, bool bMatchCase)
{/*pPartOneLength[] 是長度計算的形式參數,在 main)() 函數中調用時,pPartOneLength 是一個指向數組第一個元素的指針。在執行 main() 函數時,不知道 pPartOneLength 所表示的地址有多大的數據存儲空間,只是告訴函數:一個數據存儲空間首地址。sizoef pPartOneLength 的結果是指針變量 pPartOneLength 占內存的大小,一般在 64 位機上是8個字節。a[0] 是 int 類型,sizeof a[0] 是4個字節,結果是2。在C/C++函數中計算傳入的數組的長度是不可取的*/_Pair<int, int> paResult(-1, -1);int iStart = nPosStart >= 0 ? nPosStart : 0;if (iStart >= _nLength) return paResult;int nEnd = _nLength - sPartOne._nLength;int nAarryOtherPartLength = ctArrayOtherPart.Length;for (int i = iStart; i <= nEnd; ++i){bool bFind = true;for (int j = 0; j < sPartOne._nLength; ++j){if (bMatchCase){if (_pData[i + j] != sPartOne._pData[j]){bFind = false;break;}}else{if (gcf.gcf_tolower(_pData[i + j]) != gcf.gcf_tolower(sPartOne._pData[j])){bFind = false;break;}}}//比較第二部份if (bFind){paResult.First = i;int iStart = i + sPartOne._nLength;int k = 0;int n = 0;int nCount = 0;while (true){bool bFinish = false;for (n = 0; n < nAarryOtherPartLength; ++n){if (ctArrayOtherPart[n] == _CharType::ArabicDigit){//向后查找第一個不是數字的字符				 bool bHave = false;for (k = iStart; k < _nLength; ++k){if (!gs.c_IsArabicDigit(_pData[k])){iStart = k; //下次開始比較的位置		if (bHave){if (n == nAarryOtherPartLength - 1) //一輪比較完成{paResult.Second = k - 1;bFinish = true;++nCount;}}break;}else{bHave = true;if (k == _nLength - 1) //栓果是否最后一個字符{if (n == nAarryOtherPartLength - 1){paResult.Second = k;}return paResult;}}}}else if (ctArrayOtherPart[n] == _CharType::Punctuation){//向后查找第一個不是標點符號的字符bool bHave = false;for (k = iStart; k < _nLength; ++k){if (!gs.c_IsPunctuation(_pData[k])){iStart = k; //下次開始比較的位置		if (bHave){if (n == nAarryOtherPartLength - 1) //一輪比較完成{paResult.Second = k - 1;bFinish = true;++nCount;}}break;}else{bHave = true;if (k == _nLength - 1) //栓果是否最后一個字符{if (n == nAarryOtherPartLength - 1){paResult.Second = k;}return paResult;}}}}else if (ctArrayOtherPart[n] == _CharType::EnglishLetters){//向后查找第一個不是英文字母的字符bool bHave = false;for (k = iStart; k < _nLength; ++k){if (!gs.c_IsEnglishLetters(_pData[k])){iStart = k; //下次開始比較的位置		if (bHave){if (n == nAarryOtherPartLength - 1) //一輪比較完成{paResult.Second = k - 1;bFinish = true;++nCount;}}break;}else{bHave = true;if (k == _nLength - 1) //栓果是否最后一個字符{if (n == nAarryOtherPartLength - 1){paResult.Second = k;}return paResult;}}}}else if (ctArrayOtherPart[n] == _CharType::WhiteSpace){//向后查找第一個不是空格的字符bool bHave = false;for (k = iStart; k < _nLength; ++k){if (!gs.c_IsWhiteSpace(_pData[k])){iStart = k; //下次開始比較的位置		if (bHave){if (n == nAarryOtherPartLength - 1) //一輪比較完成{paResult.Second = k - 1;bFinish = true;++nCount;}}break;}else{bHave = true;if (k == _nLength - 1) //栓果是否最后一個字符{if (n == nAarryOtherPartLength - 1){paResult.Second = k;}return paResult;}}}}else{throw("未知字符類型!");}}if (!bFinish)  //退出 while 循環{break;}}if (nCount > 0)  //已找到匹配字符串{return paResult;}}}return paResult;
}#ifdef _STR_COMPATIBILITY_  //兼容 _StrA 與 _StrW 互相兼容/// <summary>
/// 允許 _StrW  str("abc");  而不是每次都要寫 _StrW str(_t("abc"))
/// </summary>
/// <param name="pStr">數據指針</param>
/// <param name="nBuffer">緩沖大小</param>
/// <param name="bZeroBuffer">是否把緩沖初始化為零</param>
/// 創建時間: 2023-05-08    最后一次修改時間:2023-05-08 
_StrW::_StrW(const char* pStr, const int& nBuffer, bool bZeroBuffer) :_Str<wchar_t>(gs.StringToWString(pStr).Pointer, nBuffer, bZeroBuffer)
{}_StrW::operator _StrA() const
{return gs.WStringToString(_pData,_nLength).Pointer;     
}#endif_StrA _StrW::ToStrA() const
{_StrA sResult("", _nLength);for (int i = 0; i < _nLength; ++i){sResult.Add((char)_pData[i]);}return sResult;
}_LF_END_

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/14568.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/14568.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/14568.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網創教程:WordPress插件網創自動采集并發布

網創教程&#xff1a;WordPress插件網創自動采集并發布 使用插件注意事項&#xff1a; 如果遇到404錯誤&#xff0c;請先檢查并調整網站的偽靜態設置&#xff0c;這是最常見的問題。需要定制化服務&#xff0c;請隨時聯系我。 本次更新內容 我們進行了多項更新和優化&#x…

深入解析kube-scheduler的算法自定義插件

目錄 ?編輯 一、問題引入 二、自定義步驟 三、最佳實踐考慮 一、問題引入 當涉及到 Kubernetes 集群的調度和資源分配時&#xff0c;kube-scheduler 是一個關鍵組件。kube-scheduler 負責根據集群的調度策略&#xff0c;將 Pod 分配到適當的節點上。kube-scheduler 默認使…

python爬蟲學習代碼1

百度翻譯&#xff1a;利用爬蟲技術模擬人工查詢英文單詞&#xff0c;將查到的信息保存到本地 import requests import json # 1.指定url post_url https://fanyi.baidu.com/sug # 2.UA標識 headers {"User-Agent": Mozilla/5.0 (Windows NT 10.0; Win64; x64) Appl…

pyqt6入門案例

效果預覽 hello.ui <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Dialog</class><widget class"QDialog" name"Dialog"><property name"geometry"><…

android studio接入facebook踩坑1

今天在接入facebook第三方登錄的時候&#xff0c;點擊登錄按鈕&#xff0c;APP閃退&#xff0c;并報錯 java.lang.RuntimeException Failure delivering result ResultInfo{whonull,request64206,result-1} 新文章鏈接https://lengmo714.top/facebook1.html 如下圖&#xff1a;…

OpenGL學習入門及開發環境搭建

最近學習OpenGL開發&#xff0c;被各種openGL庫搞得暈頭轉向&#xff0c;什么glut, glew glfw glad等等。 可以參考這邊博客:OpenGL 下面的 glut freeglut glfw 都是個啥_glx wgl的中文-CSDN博客 glfw是glut的升級版&#xff0c;跨平臺的主要處理窗口 事件相關。 glad是glew…

React項目知識積累(四)

1.useMemo( ) 在 React 中&#xff0c;useMemo 是一個 Hook&#xff0c;用于記憶計算結果&#xff0c;只有當依賴項之一發生變化時&#xff0c;才會重新計算。這有助于避免不必要的計算和渲染&#xff0c;從而提高應用程序的性能。 基本語法如下&#xff1a; const memoized…

html多節點生成圖片并導出zip包

html多節點生成圖片并導出zip包 背景 在做項目時遇到一個要將html節點展示的圖片列表統一導出為zip包的需求。 難點 將html節點生成圖片將多張圖片加入zip包中&#xff0c;然后下載 解決html生成圖片問題 參考html截圖的思路使用 pnpm add html-to-image如何將圖片資源生成z…

鴻蒙OS開發:【一次開發,多端部署】(多設備自適應能力)簡單介紹

多設備自適應能力 介紹 本示例是《一次開發&#xff0c;多端部署》的配套示例代碼&#xff0c;展示了[頁面開發的一多能力]&#xff0c;包括自適應布局、響應式布局、典型布局場景以及資源文件使用。 名稱簡介 開發前請熟悉鴻蒙開發指導文檔&#xff1a;gitee.com/li-shizhe…

數據可視化技術頭歌測試合集

努力是為了不平庸~ 學習的最大理由是想擺脫平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;遲一天就多一天平庸的困擾 目錄 時間趨勢可視化-柱形圖 第1關&#xff1a;“大胃王”比賽數據柱形圖繪制——繪制柱形圖的基本步驟 任務描述 相關知識 觀察和處理數據 繪…

Linux中gcc/g++的基本使用

目錄 gcc/g的使用gcc/g是如何生成可執行文件的預處理編譯匯編鏈接 庫.o文件是如何與庫鏈接的&#xff1f; debug版本和release版本 gcc/g的使用 在windows中&#xff0c;我們在VS中編寫好了代碼之后就可以直接在VS中對源碼進行編譯等操作后運行 而在Linux下&#xff0c;我們可…

LeetCode 279 —— 完全平方數

閱讀目錄 1. 題目2. 解題思路3. 代碼實現 1. 題目 2. 解題思路 此圖利用動態規劃進行求解&#xff0c;首先&#xff0c;我們求出小于 n n n 的所有完全平方數&#xff0c;存放在數組 squareNums 中。 定義 dp[n] 為和為 n n n 的完全平方數的最小數量&#xff0c;那么有狀態…

vue 展示svg矢量圖可縮放拖動

使用插件&#xff1a;svg-pan-zoom <template> <!-- svg圖--><div id"svgContainer"></div> </template><script> import svgPanZoom from svg-pan-zoom import svgFile from ../datav/img/220kVscb.svg // 路徑根據實際情況調…

MySQL存儲過程實現累加運算 1+2+…+n 等于多少?

MySQL創建存儲過程&#xff0c;實現累加運算&#xff0c;計算 12…n 等于多少。具體的代碼如下 1、實現計算123…n的和 DELIMITER // CREATE PROCEDURE sp_add_sum_num(IN n INT) BEGIN DECLARE i INT; DECLARE sum INT; SET i 1; SET sum 0;WHILE i < n DO SET sum …

若依框架實戰指南:從入門到精通

在當今快節奏的軟件開發環境中&#xff0c;選擇一個高效、可靠的開發框架至關重要。若依框架&#xff08;RuoYi&#xff09;作為一個基于Spring Boot和MyBatis的快速開發平臺&#xff0c;以其強大的功能和易用性受到了廣泛歡迎。本文將詳細介紹若依框架的使用方式&#xff0c;包…

計算機組成結構—中斷和異常

一、基本概念和分類 計算機在執行程序的過程中&#xff0c;有時會遇到一些異常情況或者特殊請求&#xff1b;這時就需要計算機暫停正在運行的程序&#xff0c;轉而先去處理這些異常或特殊請求&#xff0c;處理結束之后再返回程序的斷點處繼續執行。這種處理方式就被稱為 “中斷…

頂堅北斗有源終端有什么功能跟用途

頂堅北斗有源終端作為現代衛星導航與通信技術融合的杰出代表&#xff0c;其用途廣泛且功能強大。在廣袤無垠的偏遠山區、深邃的海洋以及荒蕪的沙漠中&#xff0c;當用戶面臨移動通信信號無法覆蓋的困境時&#xff0c;北斗有源終端便成為了連接世界的橋梁。 該終端的核心功能之一…

PE文件(六)新增節-添加代碼作業

一.手動新增節添加代碼 1.當預備條件都滿足&#xff0c;節表結尾沒有相關數據時&#xff1a; 現在我們將ipmsg.exe用winhex打開&#xff0c;在節的最后新增一個節用于存放我們要增加的數據 注意&#xff1a;飛鴿的文件對齊和內存對齊是一致的 先判斷節表末尾到第一個節之間…

奧德彪的幸福VS碼農的幸福

奧德彪的幸福 非洲國家布隆迪是一個全球最不發達國家之一&#xff0c;大部分居民以農業為生&#xff0c;其中包括香蕉&#xff0c;人們拿香蕉用來做飯也用來釀酒。 香蕉產地距離布隆迪首都布瓊布拉很遠&#xff0c;而這個國家又缺乏規模化的物流企業&#xff0c;于是就誕生了…

Linux進程--函數 system 和 popen 的區別

system() 和 popen() 是 C 語言中用于執行外部命令的兩個函數&#xff0c;它們的功能類似&#xff0c;但在使用方式和特性上有一些區別。 system() system() 函數允許您在程序中執行外部命令&#xff0c;并等待該命令執行完成后繼續執行程序。其基本語法如下&#xff1a; in…