admin 管理员组文章数量: 887021
2024年1月18日发(作者:vmos框架下载)
class CString{public: //构造函数 CString(); CString(const CString& stringSrc); CString(TCHAR ch, int nLength =1); CString(LPCTSTR lpsz); // CString(LPCSTR lpsz); ANSI下版本 //CString(LPCWSTR lpsz);UNICODE下版本 CString(LPCTSTR lpch, int nLength); //CString(LPCSTR lpch, int nLength);ANSI下版本 //CString(LPCWSTR lpch, int nLength);//UNICODE下版本 CString(const unsigned char* psz); ~CString(); //CStringData的属性 int GetLength() const; //得到字符长度 int GetAllocLength() const; //得到分配的内存长度 BOOL IsEmpty() const; //判断字符长度是否为0 operator LPCTSTR() const; //类型转换 void Empty(); //清空CStringData //操作符重载 const CString& operator=(const CString& stringSrc); const CString& operator=(LPCTSTR lpsz); const CString& operator=(TCHAR ch); const CString& operator+=(const CString& string); const CString& operator+=(TCHAR ch); const CString& operator+=(LPCTSTR lpsz); TCHAR operator[](int nIndex) const; friend CString operator+(const CString& string1,const CString& string2); friend CString operator+(const CString& string, TCHAR ch); friend CString operator+(TCHAR ch, const CString& string); friend CString operator+(const CString& string, LPCTSTR lpsz); friend CString operator+(LPCTSTR lpsz, const CString& string);
if (nLen == 0) Init(); else { CStringData* pData; { pData = (CStringData*) new BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)]; pData->nAllocLength = nLen; } pData->nRefs = 1; pData->data()[nLen] = '/0'; pData->nDataLength = nLen; m_pchData = pData->data(); }}void CString::FreeData(CStringData* pData){ delete[] (BYTE*)pData;}void CString::CopyBeforeWrite(){ if (GetData()->nRefs > 1) { CStringData* pData = GetData(); Release(); AllocBuffer(pData->nDataLength); memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(TCHAR)); } assert(GetData()->nRefs <= 1);}void CString::AllocBeforeWrite(int nLen){ if (GetData()->nRefs > 1 nLen > GetData()->nAllocLength) { Release(); AllocBuffer(nLen); } assert(GetData()->nRefs <= 1);}void CString::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData){ AllocBeforeWrite(nSrcLen); memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(TCHAR)); GetData()->nDataLength = nSrcLen; m_pchData[nSrcLen] = '/0';}
void CString::AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const{ int nNewLen = nCopyLen + nExtraLen; if (nNewLen == 0) { (); } else { uffer(nNewLen); memcpy(dest.m_pchData, m_pchData+nCopyIndex, nCopyLen*sizeof(TCHAR)); }}CString::~CString(){ if (GetData() != _afxDataNil) { if (InterlockedDecrement(&GetData()->nRefs) <= 0) FreeData(GetData()); }}CString::CString(const CString& stringSrc){ assert(a()->nRefs != 0); if (a()->nRefs >= 0) { assert(a() != _afxDataNil); m_pchData = stringSrc.m_pchData; InterlockedIncrement(&GetData()->nRefs); } else { Init(); *this = stringSrc.m_pchData; }}CString::CString(LPCTSTR lpsz){ Init(); int nLen = SafeStrlen(lpsz); if (nLen != 0) { AllocBuffer(nLen); memcpy(m_pchData, lpsz, nLen*sizeof(TCHAR)); }}
CString::CString(LPCTSTR lpch, int nLength){ Init(); if (nLength != 0) { assert(AfxIsValidAddress(lpch, nLength, FALSE)); AllocBuffer(nLength); memcpy(m_pchData, lpch, nLength*sizeof(TCHAR)); }}void CString::Release(){ if (GetData() != _afxDataNil) { assert(GetData()->nRefs != 0); if (InterlockedDecrement(&GetData()->nRefs) <= 0) FreeData(GetData()); Init(); }}void CString::Release(CStringData* pData){ if (pData != _afxDataNil) { assert(pData->nRefs != 0); if (InterlockedDecrement(&pData->nRefs) <= 0) FreeData(pData); }}void CString::Empty(){ if (GetData()->nDataLength == 0) return; if (GetData()->nRefs >= 0) Release(); else *this = &afxChNil; assert(GetData()->nDataLength == 0); assert(GetData()->nRefs < 0 GetData()->nAllocLength == 0);}
CString CString::Left(int nCount) const{ if (nCount < 0) nCount = 0; if (nCount >= GetData()->nDataLength) return *this; CString dest; AllocCopy(dest, nCount, 0, 0); return dest;}int CString::ReverseFind(TCHAR ch) const{ //从最后查找 LPTSTR lpsz = _tcsrchr(m_pchData, (_TUCHAR) ch); return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);}int CString::Find(TCHAR ch) const{ return Find(ch, 0);}int CString::Find(TCHAR ch, int nStart) const{ int nLength = GetData()->nDataLength; if (nStart >= nLength) return -1; LPTSTR lpsz = _tcschr(m_pchData + nStart, (_TUCHAR)ch); return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);}int CString::Find(LPCTSTR lpszSub) const{ return Find(lpszSub, 0);}int CString::Find(LPCTSTR lpszSub, int nStart) const{ assert(AfxIsValidString(lpszSub)); int nLength = GetData()->nDataLength; if (nStart > nLength) return -1; LPTSTR lpsz = _tcsstr(m_pchData + nStart, lpszSub); return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);}int CString::FindOneOf(LPCTSTR lpszCharSet) const{ assert(AfxIsValidString(lpszCharSet)); LPTSTR lpsz = _tcspbrk(m_pchData, lpszCharSet); return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);}
void CString::MakeUpper(){ CopyBeforeWrite(); _tcsupr(m_pchData);}void CString::MakeLower(){ CopyBeforeWrite(); _tcslwr(m_pchData);}void CString::MakeReverse(){ CopyBeforeWrite(); _tcsrev(m_pchData);}void CString::SetAt(int nIndex, TCHAR ch){ assert(nIndex >= 0); assert(nIndex < GetData()->nDataLength); CopyBeforeWrite(); m_pchData[nIndex] = ch;}void CString::TrimRight(LPCTSTR lpszTargetList){ CopyBeforeWrite(); LPTSTR lpsz = m_pchData; LPTSTR lpszLast = NULL; while (*lpsz != '/0') { if (_tcschr(lpszTargetList, *lpsz) != NULL) { if (lpszLast == NULL) lpszLast = lpsz; } else lpszLast = NULL; lpsz = _tcsinc(lpsz); } if (lpszLast != NULL) { *lpszLast = '/0'; GetData()->nDataLength = lpszLast - m_pchData; }}void CString::TrimRight(TCHAR chTarget){ CopyBeforeWrite(); LPTSTR lpsz = m_pchData; LPTSTR lpszLast = NULL;
while (*lpsz != '/0') { if (*lpsz == chTarget) { if (lpszLast == NULL) lpszLast = lpsz; } else lpszLast = NULL; lpsz = _tcsinc(lpsz); } if (lpszLast != NULL) { *lpszLast = '/0'; GetData()->nDataLength = lpszLast - m_pchData; }}void CString::TrimRight(){ CopyBeforeWrite(); LPTSTR lpsz = m_pchData; LPTSTR lpszLast = NULL; while (*lpsz != '/0') { if (_istspace(*lpsz)) { if (lpszLast == NULL) lpszLast = lpsz; } else lpszLast = NULL; lpsz = _tcsinc(lpsz); } if (lpszLast != NULL) { // truncate at trailing space start *lpszLast = '/0'; GetData()->nDataLength = lpszLast - m_pchData; }}void CString::TrimLeft(LPCTSTR lpszTargets){ // if we're not trimming anything, we're not doing any work if (SafeStrlen(lpszTargets) == 0) return; CopyBeforeWrite(); LPCTSTR lpsz = m_pchData;
while (*lpsz != '/0') { if (_tcschr(lpszTargets, *lpsz) == NULL) break; lpsz = _tcsinc(lpsz); } if (lpsz != m_pchData) { // fix up data and length int nDataLength = GetData()->nDataLength - (lpsz - m_pchData); memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR)); GetData()->nDataLength = nDataLength; }}void CString::TrimLeft(TCHAR chTarget){ CopyBeforeWrite(); LPCTSTR lpsz = m_pchData; while (chTarget == *lpsz) lpsz = _tcsinc(lpsz); if (lpsz != m_pchData) { int nDataLength = GetData()->nDataLength - (lpsz - m_pchData); memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR)); GetData()->nDataLength = nDataLength; }}void CString::TrimLeft(){ CopyBeforeWrite(); LPCTSTR lpsz = m_pchData; while (_istspace(*lpsz)) lpsz = _tcsinc(lpsz); if (lpsz != m_pchData) { int nDataLength = GetData()->nDataLength - (lpsz - m_pchData); memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR)); GetData()->nDataLength = nDataLength; }}#define TCHAR_ARG TCHAR#define WCHAR_ARG WCHAR#define CHAR_ARG charstruct _AFX_DOUBLE { BYTE doubleBits[sizeof(double)]; };
int nPrecision = 0; if (*lpsz == '.') { // skip past '.' separator (ion) lpsz = _tcsinc(lpsz); // get precision and skip it if (*lpsz == '*') { nPrecision = va_arg(argList, int); lpsz = _tcsinc(lpsz); } else { nPrecision = _ttoi(lpsz); for (; *lpsz != '/0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz)) ; } assert(nPrecision >= 0); } // should be on type modifier or specifier int nModifier = 0; if (_tcsncmp(lpsz, _T("I64"), 3) == 0) { lpsz += 3; nModifier = FORCE_INT64;#if !defined(_X86_) && !defined(_ALPHA_) // __int64 is only available on X86 and ALPHA platforms ASSERT(FALSE);#endif } else { switch (*lpsz) { // modifiers that affect size case 'h': nModifier = FORCE_ANSI; lpsz = _tcsinc(lpsz); break; case 'l': nModifier = FORCE_UNICODE; lpsz = _tcsinc(lpsz); break; // modifiers that do not affect size case 'F': case 'N': case 'L': lpsz = _tcsinc(lpsz); break; } }
// now should be on specifier switch (*lpsz | nModifier) { // single characters case 'c': case 'C': nItemLen = 2; va_arg(argList, TCHAR_ARG); break; case 'c'|FORCE_ANSI: case 'C'|FORCE_ANSI: nItemLen = 2; va_arg(argList, CHAR_ARG); break; case 'c'|FORCE_UNICODE: case 'C'|FORCE_UNICODE: nItemLen = 2; va_arg(argList, WCHAR_ARG); break; // strings case 's': { LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR); if (pstrNextArg == NULL) nItemLen = 6; // "(null)" else { nItemLen = lstrlen(pstrNextArg); nItemLen = max(1, nItemLen); } } break;
case 'S': {#ifndef _UNICODE LPWSTR pstrNextArg = va_arg(argList, LPWSTR); if (pstrNextArg == NULL) nItemLen = 6; // "(null)" else { nItemLen = wcslen(pstrNextArg); nItemLen = max(1, nItemLen); }#else LPCSTR pstrNextArg = va_arg(argList, LPCSTR); if (pstrNextArg == NULL) nItemLen = 6; // "(null)" else { nItemLen = lstrlenA(pstrNextArg); nItemLen = max(1, nItemLen); }#endif } break; case 's'|FORCE_ANSI: case 'S'|FORCE_ANSI: { LPCSTR pstrNextArg = va_arg(argList, LPCSTR); if (pstrNextArg == NULL) nItemLen = 6; // "(null)" else { nItemLen = lstrlenA(pstrNextArg); nItemLen = max(1, nItemLen); } } break; case 's'|FORCE_UNICODE: case 'S'|FORCE_UNICODE: { LPWSTR pstrNextArg = va_arg(argList, LPWSTR); if (pstrNextArg == NULL) nItemLen = 6; // "(null)" else { nItemLen = wcslen(pstrNextArg); nItemLen = max(1, nItemLen); } } break; }
// adjust nItemLen for strings if (nItemLen != 0) { if (nPrecision != 0) nItemLen = min(nItemLen, nPrecision); nItemLen = max(nItemLen, nWidth); } else { switch (*lpsz) { // integers case 'd': case 'i': case 'u': case 'x': case 'X': case 'o': if (nModifier & FORCE_INT64) va_arg(argList, __int64); else va_arg(argList, int); nItemLen = 32; nItemLen = max(nItemLen, nWidth+nPrecision); break; case 'e': case 'g': case 'G': va_arg(argList, DOUBLE_ARG); nItemLen = 128; nItemLen = max(nItemLen, nWidth+nPrecision); break; case 'f': { double f; LPTSTR pszTemp; // 312 == strlen("-1+(309 zeroes).") // 309 zeroes == max precision of a double // 6 == adjustment in case precision is not specified, // which means that the precision defaults to 6 pszTemp = (LPTSTR)_alloca(max(nWidth, 312+nPrecision+6)); f = va_arg(argList, double); _stprintf( pszTemp, _T( "%*.*f" ), nWidth, nPrecision+6, f ); nItemLen = _tcslen(pszTemp); } break; case 'p': va_arg(argList, void*); nItemLen = 32; nItemLen = max(nItemLen, nWidth+nPrecision); break;
// no output case 'n': va_arg(argList, int*); break; default: assert(FALSE); // unknown formatting option } } // adjust nMaxLen for output nItemLen nMaxLen += nItemLen; } GetBuffer(nMaxLen); //VERIFY(_vstprintf(m_pchData, lpszFormat, argListSave) <= GetAllocLength()); _vstprintf(m_pchData, lpszFormat, argListSave); ReleaseBuffer(); va_end(argListSave);}void CString::Format(LPCTSTR lpszFormat, ...){ assert(AfxIsValidString(lpszFormat)); va_list argList; va_start(argList, lpszFormat); FormatV(lpszFormat, argList); va_end(argList);}void CString::ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data,int nSrc2Len, LPCTSTR lpszSrc2Data){ int nNewLen = nSrc1Len + nSrc2Len; if (nNewLen != 0) { AllocBuffer(nNewLen); memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(TCHAR)); memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(TCHAR)); }}
void CString::ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData){ if (nSrcLen == 0) return;
if (GetData()->nRefs > 1 GetData()->nDataLength + nSrcLen > GetData()->nAllocLength) {//动态分配 CStringData* pOldData = GetData(); ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData); assert(pOldData != NULL); CString::Release(pOldData); } else {//直接往后添加 memcpy(m_pchData+GetData()->nDataLength, lpszSrcData, nSrcLen*sizeof(TCHAR)); GetData()->nDataLength += nSrcLen; assert(GetData()->nDataLength <= GetData()->nAllocLength); m_pchData[GetData()->nDataLength] = '/0'; }}const CString& CString::operator+=(LPCTSTR lpsz){ assert(lpsz == NULL AfxIsValidString(lpsz)); ConcatInPlace(SafeStrlen(lpsz), lpsz); return *this;}const CString& CString::operator+=(TCHAR ch){ ConcatInPlace(1, &ch); return *this;}const CString& CString::operator+=(const CString& string){ ConcatInPlace(a()->nDataLength, string.m_pchData); return *this;}
LPTSTR CString::GetBuffer(int nMinBufLength){ assert(nMinBufLength >= 0); if (GetData()->nRefs > 1 nMinBufLength > GetData()->nAllocLength) { //重新动态分配 CStringData* pOldData = GetData(); int nOldLen = GetData()->nDataLength; // AllocBuffer will tromp it if (nMinBufLength < nOldLen) nMinBufLength = nOldLen; AllocBuffer(nMinBufLength); memcpy(m_pchData, pOldData->data(), (nOldLen+1)*sizeof(TCHAR)); GetData()->nDataLength = nOldLen; CString::Release(pOldData); } assert(GetData()->nRefs <= 1); assert(m_pchData != NULL); return m_pchData;}void CString::ReleaseBuffer(int nNewLength){ CopyBeforeWrite(); //脱离共享数据块, if (nNewLength == -1) nNewLength = lstrlen(m_pchData); // zero terminated assert(nNewLength <= GetData()->nAllocLength); GetData()->nDataLength = nNewLength; m_pchData[nNewLength] = '/0';}LPTSTR CString::GetBufferSetLength(int nNewLength){ assert(nNewLength >= 0); GetBuffer(nNewLength); GetData()->nDataLength = nNewLength; m_pchData[nNewLength] = '/0'; return m_pchData;}void CString::FreeExtra(){ assert(GetData()->nDataLength <= GetData()->nAllocLength); if (GetData()->nDataLength != GetData()->nAllocLength) { CStringData* pOldData = GetData(); AllocBuffer(GetData()->nDataLength); memcpy(m_pchData, pOldData->data(), pOldData->nDataLength*sizeof(TCHAR)); assert(m_pchData[GetData()->nDataLength] == '/0'); CString::Release(pOldData); } assert(GetData() != NULL);}
LPTSTR CString::LockBuffer(){ LPTSTR lpsz = GetBuffer(0); GetData()->nRefs = -1; return lpsz;}void CString::UnlockBuffer(){ assert(GetData()->nRefs == -1); if (GetData() != _afxDataNil) GetData()->nRefs = 1;}int CString::Compare(LPCTSTR lpsz) const{ assert(AfxIsValidString(lpsz)); return _tcscmp(m_pchData, lpsz);}int CString::CompareNoCase(LPCTSTR lpsz) const{ assert(AfxIsValidString(lpsz)); return _tcsicmp(m_pchData, lpsz);}
// CString::Collate is often slower than Compare but is MBSC/Unicode// aware as well as locale-sensitive with respect to sort CString::Collate(LPCTSTR lpsz) const{ assert(AfxIsValidString(lpsz)); return _tcscoll(m_pchData, lpsz);}
int CString::CollateNoCase(LPCTSTR lpsz) const{ assert(AfxIsValidString(lpsz)); return _tcsicoll(m_pchData, lpsz);}
TCHAR CString::GetAt(int nIndex) const{ assert(nIndex >= 0); assert(nIndex < GetData()->nDataLength); return m_pchData[nIndex];}TCHAR CString::operator[](int nIndex) const{ assert(nIndex >= 0); assert(nIndex < GetData()->nDataLength); return m_pchData[nIndex];}
CString operator+(const CString& string1, const CString& string2){ CString s; Copy(a()->nDataLength, string1.m_pchData, a()->nDataLength, string2.m_pchData); return s;}CString operator+(const CString& string, LPCTSTR lpsz){ assert(lpsz == NULL AfxIsValidString(lpsz)); CString s; Copy(a()->nDataLength, string.m_pchData, CString::SafeStrlen(lpsz), lpsz); return s;}CString operator+(LPCTSTR lpsz, const CString& string){ assert(lpsz == NULL AfxIsValidString(lpsz)); CString s; Copy(CString::SafeStrlen(lpsz), lpsz, a()->nDataLength, string.m_pchData); return s;}bool operator==(const CString& s1, const CString& s2){ return e(s2) == 0; }bool operator==(const CString& s1, LPCTSTR s2){ return e(s2) == 0; }bool operator==(LPCTSTR s1, const CString& s2){ return e(s1) == 0; }bool operator!=(const CString& s1, const CString& s2){ return e(s2) != 0; }bool operator!=(const CString& s1, LPCTSTR s2){ return e(s2) != 0; }bool operator!=(LPCTSTR s1, const CString& s2){ return e(s1) != 0; }bool operator<(const CString& s1, const CString& s2){ return e(s2) < 0; }bool operator<(const CString& s1, LPCTSTR s2){ return e(s2) < 0; }bool operator<(LPCTSTR s1, const CString& s2){ return e(s1) > 0; }bool operator>(const CString& s1, const CString& s2){ return e(s2) > 0; }bool operator>(const CString& s1, LPCTSTR s2){ return e(s2) > 0; }
bool operator>(LPCTSTR s1, const CString& s2){ return e(s1) < 0; }bool operator<=(const CString& s1, const CString& s2){ return e(s2) <= 0; }bool operator<=(const CString& s1, LPCTSTR s2){ return e(s2) <= 0; }bool operator<=(LPCTSTR s1, const CString& s2){ return e(s1) >= 0; }bool operator>=(const CString& s1, const CString& s2){ return e(s2) >= 0; }bool operator>=(const CString& s1, LPCTSTR s2){ return e(s2) >= 0; }bool operator>=(LPCTSTR s1, const CString& s2){ return e(s1) <= 0; }void ConstructElements(CString* pElements, int nCount){ assert(nCount == 0
AfxIsValidAddress(pElements, nCount * sizeof(CString))); for (; nCount--; ++pElements) memcpy(pElements, &AfxGetEmptyString(), sizeof(*pElements));}void DestructElements(CString* pElements, int nCount){ assert(nCount == 0
AfxIsValidAddress(pElements, nCount * sizeof(CString))); for (; nCount--; ++pElements) pElements->~CString();}
void CopyElements(CString* pDest, const CString* pSrc, int nCount){ assert(nCount == 0
AfxIsValidAddress(pDest, nCount * sizeof(CString))); assert(nCount == 0
AfxIsValidAddress(pSrc, nCount * sizeof(CString))); for (; nCount--; ++pDest, ++pSrc) *pDest = *pSrc;}
版权声明:本文标题:MFC字符串类CString源代码 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1705557952h489868.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论