⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strclass.cpp

📁 墨香最新私服
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		for (int i = 0; i < nLength; i++)
			m_pchData[i] = ch;
#else
		memset(m_pchData, ch, nLength);
#endif
	}
}

CStrClass::CStrClass(LPCTSTR lpch, int nLength)
{
	if (nLength == 0)
		Init();
	else
	{
		AllocBuffer(nLength);
		memcpy(m_pchData, lpch, nLength*sizeof(TCHAR));
	}
}

//////////////////////////////////////////////////////////////////////////////
// Assignment operators

const CStrClass& CStrClass::operator=(TCHAR ch)
{
	AssignCopy(1, &ch);
	return *this;
}

//////////////////////////////////////////////////////////////////////////////
// less common string expressions

CStrClass __cdecl operator+(const CStrClass& string1, TCHAR ch)
{
	CStrClass s;
	s.ConcatCopy(string1.m_nDataLength, string1.m_pchData, 1, &ch);
	return s;
}

CStrClass __cdecl operator+(TCHAR ch, const CStrClass& string)
{
	CStrClass s;
	s.ConcatCopy(1, &ch, string.m_nDataLength, string.m_pchData);
	return s;
}

//////////////////////////////////////////////////////////////////////////////
// Very simple sub-string extraction

CStrClass CStrClass::Mid(int nFirst) const
{
	return Mid(nFirst, m_nDataLength - nFirst);
}

CStrClass CStrClass::Mid(int nFirst, int nCount) const
{
	// out-of-bounds requests return sensible things
	if (nFirst + nCount > m_nDataLength)
		nCount = m_nDataLength - nFirst;
	if (nFirst > m_nDataLength)
		nCount = 0;

	CStrClass dest;
	AllocCopy(dest, nCount, nFirst, 0);
	return dest;
}

CStrClass CStrClass::Right(int nCount) const
{

	if (nCount > m_nDataLength)
		nCount = m_nDataLength;

	CStrClass dest;
	AllocCopy(dest, nCount, m_nDataLength-nCount, 0);
	return dest;
}

CStrClass CStrClass::Left(int nCount) const
{

	if (nCount > m_nDataLength)
		nCount = m_nDataLength;

	CStrClass dest;
	AllocCopy(dest, nCount, 0, 0);
	return dest;
}

// strspn equivalent
CStrClass CStrClass::SpanIncluding(LPCTSTR lpszCharSet) const
{
	return Left(_tcsspn(m_pchData, lpszCharSet));
}

// strcspn equivalent
CStrClass CStrClass::SpanExcluding(LPCTSTR lpszCharSet) const
{
	return Left(_tcscspn(m_pchData, lpszCharSet));
}

//////////////////////////////////////////////////////////////////////////////
// Finding

int CStrClass::ReverseFind(TCHAR ch) const
{
	// find last single character
	LPTSTR lpsz = _tcsrchr(m_pchData, ch);

	// return -1 if not found, distance from beginning otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

// find a sub-string (like strstr)
int CStrClass::Find(LPCTSTR lpszSub) const
{

	// find first matching substring
	LPTSTR lpsz = _tcsstr(m_pchData, lpszSub);

	// return -1 for not found, distance from beginning otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

/////////////////////////////////////////////////////////////////////////////
// CStrClass formatting

#define FORCE_ANSI		0x10000
#define FORCE_UNICODE	0x20000

// formatting (using wsprintf style formatting)
void __cdecl CStrClass::Format(LPCTSTR lpszFormat, ...)
{
	va_list argList;
	va_start(argList, lpszFormat);

	// make a guess at the maximum length of the resulting string
	int nMaxLen = 0;
	for (LPCTSTR lpsz = lpszFormat; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
	{
		// handle '%' character, but watch out for '%%'
		if (*lpsz != '%' || *(lpsz = _tcsinc(lpsz)) == '%')
		{
			nMaxLen += _tclen(lpsz);
			continue;
		}

		int nItemLen = 0;

		// handle '%' character with format
		int nWidth = 0;
		for (; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
		{
			// check for valid flags
			if (*lpsz == '#')
				nMaxLen += 2;	// for '0x'
			else if (*lpsz == '*')
				nWidth = *va_arg(argList, int*);
			else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' ||
				*lpsz == ' ')
				;
			else // hit non-flag character
				break;
		}
		// get width and skip it
		if (nWidth == 0)
		{
			// width indicated by
			int nWidth = _ttoi(lpsz);
			for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
				;
		}

		int nPrecision = 0;
		if (*lpsz == '.')
		{
			// skip past '.' separator (width.precision)
			lpsz = _tcsinc(lpsz);

			// get precision and skip it
			if (*lpsz == '*')
				nPrecision = *va_arg(argList, int*);
			else
			{
				nPrecision = _ttoi(lpsz);
				for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
					;
			}
		}

		// should be on type modifier or specifier
		int nModifier = 0;
		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);
			break;
		case 'c'|FORCE_ANSI:
		case 'C'|FORCE_ANSI:
			nItemLen = 2;
			va_arg(argList, char);
			break;
		case 'c'|FORCE_UNICODE:
		case 'C'|FORCE_UNICODE:
			nItemLen = 2;
			va_arg(argList, WCHAR);
			break;

		// strings
		case 's':
		case 'S':
			nItemLen = lstrlen(va_arg(argList, LPCTSTR));
			nItemLen = max(1, nItemLen);
			break;
		case 's'|FORCE_ANSI:
		case 'S'|FORCE_ANSI:
			nItemLen = lstrlenA(va_arg(argList, LPCSTR));
			nItemLen = max(1, nItemLen);
			break;
#ifndef _MAC
		case 's'|FORCE_UNICODE:
		case 'S'|FORCE_UNICODE:
			nItemLen = wcslen(va_arg(argList, LPWSTR));
			nItemLen = max(1, nItemLen);
			break;
#endif
		}

		// adjust nItemLen for strings
		if (nItemLen != 0)
		{
			nItemLen = max(nItemLen, nWidth);
			if (nPrecision != 0)
				nItemLen = min(nItemLen, nPrecision);
		}
		else
		{
			switch (*lpsz)
			{
			// integers
			case 'd':
			case 'i':
			case 'u':
			case 'x':
			case 'X':
			case 'o':
				va_arg(argList, int);
				nItemLen = 32;
				nItemLen = max(nItemLen, nWidth+nPrecision);
				break;

			case 'e':
			case 'f':
			case 'g':
			case 'G':
				va_arg(argList, double);
				nItemLen = 32;
				nItemLen = max(nItemLen, nWidth+nPrecision);
				break;

			case 'p':
				va_arg(argList, void*);
				nItemLen = 32;
				nItemLen = max(nItemLen, nWidth+nPrecision);
				break;

			// no output
			case 'n':
				va_arg(argList, int*);
				break;
			}
		}

		// adjust nMaxLen for output nItemLen
		nMaxLen += nItemLen;
	}
	va_end(argList);

	// finally, set the buffer length and format the string
	va_start(argList, lpszFormat);	// restart the arg list
	GetBuffer(nMaxLen);
	ReleaseBuffer();
	va_end(argList);
}

///////////////////////////////////////////////////////////////////////////////
// CStrClass support for template collections

void __cdecl ConstructElements(CStrClass* pElements, int nCount)
{
	for (; nCount--; ++pElements)
		memcpy(pElements, &jazzidEmptyString, sizeof(*pElements));
}

void __cdecl DestructElements(CStrClass* pElements, int nCount)
{
	for (; nCount--; ++pElements)
		pElements->Empty();
}

UINT __cdecl HashKey(LPCTSTR key)
{
	UINT nHash = 0;
	while (*key)
		nHash = (nHash<<5) + nHash + *key++;
	return nHash;
}

///////////////////////////////////////////////////////////////////////////////
// CStrClass
 CStrClass::CStrClass(const unsigned char* lpsz)
	{ Init(); *this = (LPCSTR)lpsz; }
 const CStrClass& CStrClass::operator=(const unsigned char* lpsz)
	{ *this = (LPCSTR)lpsz; return *this; }
#ifdef _UNICODE
 const CStrClass& CStrClass::operator+=(char ch)
	{ *this += (TCHAR)ch; return *this; }
 const CStrClass& CStrClass::operator=(char ch)
	{ *this = (TCHAR)ch; return *this; }
 CStrClass __cdecl operator+(const CStrClass& string, char ch)
	{ return string + (TCHAR)ch; }
 CStrClass __cdecl operator+(char ch, const CStrClass& string)
	{ return (TCHAR)ch + string; }
#endif

 int CStrClass::GetAllocLength() const
	{ return m_nAllocLength; }
 BOOL CStrClass::IsEmpty() const
	{ return m_nDataLength == 0; }
 CStrClass::operator LPCTSTR() const
	{ return (LPCTSTR)m_pchData; }
 int CStrClass::SafeStrlen(LPCTSTR lpsz)
	{ return (lpsz == NULL) ? NULL : _tcslen(lpsz); }

// CStrClass support (windows specific)
 int CStrClass::Compare(LPCTSTR lpsz) const
	{ return _tcscmp(m_pchData, lpsz); }	// MBCS/Unicode aware
 int CStrClass::CompareNoCase(LPCTSTR lpsz) const
	{ return _tcsicmp(m_pchData, lpsz); }	// MBCS/Unicode aware
// CStrClass::Collate is often slower than Compare but is MBSC/Unicode
//	aware as well as locale-sensitive with respect to sort order.
 int CStrClass::Collate(LPCTSTR lpsz) const
	{ return _tcscoll(m_pchData, lpsz); }	// locale sensitive
 void CStrClass::MakeUpper()
	{ ::CharUpper(m_pchData); }
 void CStrClass::MakeLower()
	{ ::CharLower(m_pchData); }

 void CStrClass::MakeReverse()
	{ _tcsrev(m_pchData); }
 TCHAR CStrClass::GetAt(int nIndex) const
	{
		if (nIndex < 0) return 0;
		if (nIndex > m_nDataLength) return 0;

		return m_pchData[nIndex];
	}
 TCHAR CStrClass::operator[](int nIndex) const
	{
		// same as GetAt

		if (nIndex < 0) return 0;
		if (nIndex > m_nDataLength) return 0;

		return m_pchData[nIndex];
	}
 void CStrClass::SetAt(int nIndex, TCHAR ch)
	{
		if (nIndex < 0) return;
		if (nIndex > m_nDataLength) return;
		if (ch == 0) return;

		m_pchData[nIndex] = ch;
	}
 BOOL __cdecl operator==(const CStrClass& s1, const CStrClass& s2)
	{ return s1.Compare(s2) == 0; }
 BOOL __cdecl operator==(const CStrClass& s1, LPCTSTR s2)
	{ return s1.Compare(s2) == 0; }
 BOOL __cdecl operator==(LPCTSTR s1, const CStrClass& s2)
	{ return s2.Compare(s1) == 0; }
 BOOL __cdecl operator!=(const CStrClass& s1, const CStrClass& s2)
	{ return s1.Compare(s2) != 0; }
 BOOL __cdecl operator!=(const CStrClass& s1, LPCTSTR s2)
	{ return s1.Compare(s2) != 0; }
 BOOL __cdecl operator!=(LPCTSTR s1, const CStrClass& s2)
	{ return s2.Compare(s1) != 0; }
 BOOL __cdecl operator<(const CStrClass& s1, const CStrClass& s2)
	{ return s1.Compare(s2) < 0; }
 BOOL __cdecl operator<(const CStrClass& s1, LPCTSTR s2)
	{ return s1.Compare(s2) < 0; }
 BOOL __cdecl operator<(LPCTSTR s1, const CStrClass& s2)
	{ return s2.Compare(s1) > 0; }
 BOOL __cdecl operator>(const CStrClass& s1, const CStrClass& s2)
	{ return s1.Compare(s2) > 0; }
 BOOL __cdecl operator>(const CStrClass& s1, LPCTSTR s2)
	{ return s1.Compare(s2) > 0; }
 BOOL __cdecl operator>(LPCTSTR s1, const CStrClass& s2)
	{ return s2.Compare(s1) < 0; }
 BOOL __cdecl operator<=(const CStrClass& s1, const CStrClass& s2)
	{ return s1.Compare(s2) <= 0; }
 BOOL __cdecl operator<=(const CStrClass& s1, LPCTSTR s2)
	{ return s1.Compare(s2) <= 0; }
 BOOL __cdecl operator<=(LPCTSTR s1, const CStrClass& s2)
	{ return s2.Compare(s1) >= 0; }
 BOOL __cdecl operator>=(const CStrClass& s1, const CStrClass& s2)
	{ return s1.Compare(s2) >= 0; }
 BOOL __cdecl operator>=(const CStrClass& s1, LPCTSTR s2)
	{ return s1.Compare(s2) >= 0; }
 BOOL __cdecl operator>=(LPCTSTR s1, const CStrClass& s2)
	{ return s2.Compare(s1) <= 0; }

#ifndef _UNICODE
 void CStrClass::AnsiToOem()
	{ ::AnsiToOem(m_pchData, m_pchData); }
 void CStrClass::OemToAnsi()
	{ ::OemToAnsi(m_pchData, m_pchData); }
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -