📄 cstr.cpp
字号:
stringData.nDataLength = lpszLast - stringData.data + 1;
}
}
void CStr::TrimRight(TCHAR chTarget)
{
// find beginning of trailing matches
// by starting at beginning (DBCS aware)
LPTSTR lpsz = stringData.data;
LPTSTR lpszLast = NULL;
while (*lpsz != '\0')
{
if (*lpsz == chTarget)
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
lpszLast = NULL;
lpsz = _tcsinc(lpsz);
}
if (lpszLast != NULL)
{
// truncate at left-most matching character
*lpszLast = '\0';
stringData.nDataLength = lpszLast - stringData.data + 1;
}
}
void CStr::TrimRight()
{
// find beginning of trailing spaces by starting at beginning (DBCS aware)
LPTSTR lpsz = stringData.data;
LPTSTR lpszLast = NULL;
while (*lpsz != '\0')
{
if (iswspace(*lpsz))
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
lpszLast = NULL;
lpsz = _tcsinc(lpsz);
}
if (lpszLast != NULL)
{
// truncate at trailing space start
*lpszLast = '\0';
stringData.nDataLength = lpszLast - stringData.data + 1;
}
}
void CStr::TrimLeft(LPCTSTR lpszTargets)
{
// if we're not trimming anything, we're not doing any work
if (wcslen(lpszTargets) == 0)
return;
LPCTSTR lpsz = stringData.data;
while (*lpsz != '\0')
{
if (wcschr(lpszTargets, *lpsz) == NULL)
break;
lpsz = _tcsinc(lpsz);
}
if (lpsz != stringData.data)
{
// fix up data and length
int nDataLength = stringData.nDataLength - (lpsz - stringData.data);
LPTSTR newData = (LPTSTR)malloc( nDataLength*sizeof(TCHAR) );
memcpy(newData, lpsz, (nDataLength)*sizeof(TCHAR));
free( stringData.data );
stringData.data = newData;
stringData.nDataLength = nDataLength;
stringData.nAllocLength = nDataLength;
}
}
void CStr::TrimLeft(TCHAR chTarget)
{
// find first non-matching character
LPCTSTR lpsz = stringData.data;
while (chTarget == *lpsz)
lpsz = _tcsinc(lpsz);
if (lpsz != stringData.data)
{
// fix up data and length
int nDataLength = stringData.nDataLength - (lpsz - stringData.data);
LPTSTR newData = (LPTSTR)malloc( nDataLength*sizeof(TCHAR) );
memcpy(newData, lpsz, (nDataLength)*sizeof(TCHAR));
free( stringData.data );
stringData.data = newData;
stringData.nDataLength = nDataLength;
stringData.nAllocLength = nDataLength;
}
}
void CStr::TrimLeft()
{
// find first non-space character
LPCTSTR lpsz = stringData.data;
while (iswspace(*lpsz))
lpsz = _tcsinc(lpsz);
if (lpsz != stringData.data)
{
// fix up data and length
int nDataLength = stringData.nDataLength - (lpsz - stringData.data);
LPTSTR newData = (LPTSTR)malloc( nDataLength*sizeof(TCHAR) );
memcpy(newData, lpsz, (nDataLength)*sizeof(TCHAR));
free( stringData.data );
stringData.data = newData;
stringData.nDataLength = nDataLength;
stringData.nAllocLength = nDataLength;
}
}
//////////////////////////////////////////////////////////////////////////////
// Very simple sub-string extraction
CStr CStr::Mid(int nFirst) const
{
return Mid(nFirst, stringData.nDataLength - nFirst - 1);
}
CStr CStr::Mid(int nFirst, int nCount) const
{
// out-of-bounds requests return sensible things
if (nFirst < 0)
nFirst = 0;
if (nCount < 0)
nCount = 0;
if (nFirst + nCount >= stringData.nDataLength)
nCount = stringData.nDataLength - nFirst - 1;
if (nFirst >= stringData.nDataLength)
nCount = 0;
// optimize case of returning entire string
if (nFirst == 0 && nFirst + nCount == stringData.nDataLength)
return *this;
CStr dest;
AllocCopy(dest, nCount, nFirst, 0);
return dest;
}
CStr CStr::Right(int nCount) const
{
if (nCount < 0)
nCount = 0;
if (nCount >= stringData.nDataLength-1)
return *this;
CStr dest;
AllocCopy(dest, nCount, stringData.nDataLength-nCount-1, 0);
return dest;
}
CStr CStr::Left(int nCount) const
{
if (nCount < 0)
nCount = 0;
if (nCount >= stringData.nDataLength-1)
return *this;
CStr dest;
AllocCopy(dest, nCount, 0, 0);
return dest;
}
int CStr::Replace(TCHAR chOld, TCHAR chNew)
{
int nCount = 0;
// short-circuit the nop case
if (chOld != chNew)
{
// otherwise modify each character that matches in the string
LPTSTR psz = stringData.data;
LPTSTR pszEnd = psz + stringData.nDataLength;
while (psz < pszEnd)
{
// replace instances of the specified character only
if (*psz == chOld)
{
*psz = chNew;
nCount++;
}
psz = _tcsinc(psz);
}
}
return nCount;
}
int CStr::Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
{
// can't have empty or NULL lpszOld
int nSourceLen = wcslen(lpszOld);
if (nSourceLen == 0)
return 0;
int nReplacementLen = wcslen(lpszNew);
// loop once to figure out the size of the result string
int nCount = 0;
LPTSTR lpszStart = stringData.data;
LPTSTR lpszEnd = stringData.data + stringData.nDataLength;
LPTSTR lpszTarget;
while (lpszStart < lpszEnd)
{
while ((lpszTarget = wcsstr(lpszStart, lpszOld)) != NULL)
{
nCount++;
lpszStart = lpszTarget + nSourceLen;
}
lpszStart += lstrlen(lpszStart) + 1;
}
// if any changes were made, make them
if (nCount > 0)
{
// if the buffer is too small, just
// allocate a new buffer (slow but sure)
int nOldLength = stringData.nDataLength;
int nNewLength = nOldLength + (nReplacementLen-nSourceLen)*nCount;
if (stringData.nAllocLength < nNewLength)
{
LPTSTR pstr = stringData.data;
stringData.data = (LPTSTR)malloc( nNewLength*sizeof(TCHAR) );
stringData.nAllocLength = nNewLength;
memcpy(stringData.data, pstr, nOldLength*sizeof(TCHAR));
free( pstr );
}
// else, we just do it in-place
lpszStart = stringData.data;
lpszEnd = stringData.data + stringData.nDataLength;
// loop again to actually do the work
while (lpszStart < lpszEnd)
{
while ( (lpszTarget = wcsstr(lpszStart, lpszOld)) != NULL)
{
int nBalance = nOldLength - (lpszTarget - stringData.data + nSourceLen);
memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
nBalance * sizeof(TCHAR));
memcpy(lpszTarget, lpszNew, nReplacementLen*sizeof(TCHAR));
lpszStart = lpszTarget + nReplacementLen;
lpszStart[nBalance-1] = '\0';
nOldLength += (nReplacementLen - nSourceLen);
}
lpszStart += lstrlen(lpszStart) + 1;
}
ASSERT(stringData.data[nNewLength-1] == '\0');
stringData.nDataLength = nNewLength;
}
return nCount;
}
// formatting (using wsprintf style formatting)
void CStr::Format(LPCTSTR lpszFormat, ...)
{
free( stringData.data );
stringData.nAllocLength = wcslen(lpszFormat)+16384;
stringData.data = (LPTSTR)malloc( stringData.nAllocLength * sizeof(TCHAR) );
va_list argList;
va_start(argList, lpszFormat);
stringData.nDataLength = _vsnwprintf( stringData.data, stringData.nAllocLength, lpszFormat, argList ) + 1;
va_end(argList);
FreeExtra();
}
int CStr::CompareNoCase(LPCTSTR string) const
{
return wcsicmp( stringData.data, string);
}
int CStr::Compare(LPCTSTR string) const
{
return wcscmp( stringData.data, string);
}
bool operator==(const CStr& s1, const CStr& s2)
{
return ( wcscmp( (LPCTSTR)s1, (LPCTSTR)s2) == 0 );
}
bool operator==(const CStr& s1, LPCTSTR s2)
{
return ( wcscmp( (LPCTSTR)s1, s2) == 0 );
}
bool operator==(LPCTSTR s1, const CStr& s2)
{
return ( wcscmp( s1, (LPCTSTR)s2) == 0 );
}
bool operator!=(const CStr& s1, const CStr& s2)
{
return ( wcscmp( (LPCTSTR)s1, (LPCTSTR)s2) != 0 );
}
bool operator!=(const CStr& s1, LPCTSTR s2)
{
return ( wcscmp( (LPCTSTR)s1, s2) != 0 );
}
bool operator!=(LPCTSTR s1, const CStr& s2)
{
return ( wcscmp( s1, (LPCTSTR)s2) != 0 );
}
/*
void CStr::MakeReverse()
{
_tcsrev( stringData.data );
}
void CStr::SetAt(int nIndex, TCHAR ch)
{
ASSERT(nIndex >= 0);
ASSERT(nIndex < stringData.nDataLength);
stringData.data[nIndex] = ch;
}
///////////////////////////////////////////////////////////////////////////////
// CStr conversion helpers (these use the current system locale)
int AFX_CDECL _wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count)
{
if (count == 0 && mbstr != NULL)
return 0;
int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1,
mbstr, count, NULL, NULL);
ASSERT(mbstr == NULL || result <= (int)count);
if (result > 0)
mbstr[result-1] = 0;
return result;
}
int AFX_CDECL _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count)
{
if (count == 0 && wcstr != NULL)
return 0;
int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1,
wcstr, count);
ASSERT(wcstr == NULL || result <= (int)count);
if (result > 0)
wcstr[result-1] = 0;
return result;
}
LPWSTR AFXAPI AfxA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
{
if (lpa == NULL)
return NULL;
ASSERT(lpw != NULL);
// verify that no illegal character present
// since lpw was allocated based on the size of lpa
// don't worry about the number of chars
lpw[0] = '\0';
VERIFY(MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars));
return lpw;
}
LPSTR AFXAPI AfxW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
{
if (lpw == NULL)
return NULL;
ASSERT(lpa != NULL);
// verify that no illegal character present
// since lpa was allocated based on the size of lpw
// don't worry about the number of chars
lpa[0] = '\0';
VERIFY(WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL));
return lpa;
}
//////////////////////////////////////////////////////////////////////////////
// Assignment operators
const CStr& CStr::operator=(TCHAR ch)
{
AssignCopy(1, &ch);
return *this;
}
//////////////////////////////////////////////////////////////////////////////
// less common string expressions
CStr AFXAPI operator+(const CStr& string1, TCHAR ch)
{
CStr s;
s.ConcatCopy(string1.stringData.nDataLength, string1.stringData.data, 1, &ch);
return s;
}
CStr AFXAPI operator+(TCHAR ch, const CStr& string)
{
CStr s;
s.ConcatCopy(1, &ch, string.stringData.nDataLength, string.stringData.data);
return s;
}
//////////////////////////////////////////////////////////////////////////////
// Advanced manipulation
int CStr::Delete(int nIndex, int nCount )
{
if (nIndex < 0)
nIndex = 0;
int nNewLength = stringData.nDataLength;
#if defined(_WIN32_WCE)
if (nCount > nNewLength)
nCount = nNewLength;
#endif
if (nCount > 0 && nIndex < nNewLength)
{
CopyBeforeWrite();
int nBytesToCopy = nNewLength - (nIndex + nCount) + 1;
WCE_FCTN(memcpy)(stringData.data + nIndex,
stringData.data + nIndex + nCount, nBytesToCopy * sizeof(TCHAR));
stringData.nDataLength = nNewLength - nCount;
}
return nNewLength;
}
int CStr::Insert(int nIndex, TCHAR ch)
{
CopyBeforeWrite();
if (nIndex < 0)
nIndex = 0;
int nNewLength = stringData.nDataLength;
if (nIndex > nNewLength)
nIndex = nNewLength;
nNewLength++;
if (stringData.nAllocLength < nNewLength)
{
CStrData* pOldData = GetData();
LPTSTR pstr = stringData.data;
AllocBuffer(nNewLength);
WCE_FCTN(memcpy)(stringData.data, pstr, (pOldData->nDataLength+1)*sizeof(TCHAR));
CStr::Release(pOldData);
}
// move existing bytes down
WCE_FCTN(memcpy)(stringData.data + nIndex + 1,
stringData.data + nIndex, (nNewLength-nIndex)*sizeof(TCHAR));
stringData.data[nIndex] = ch;
stringData.nDataLength = nNewLength;
return nNewLength;
}
int CStr::Insert(int nIndex, LPCTSTR pstr)
{
if (nIndex < 0)
nIndex = 0;
int nInsertLength = SafeStrlen(pstr);
int nNewLength = stringData.nDataLength;
if (nInsertLength > 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -