📄 string.cpp
字号:
//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String& C_String::operator += (s32 iNumber){ *this += C_String(iNumber); return *this;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String& C_String::operator += (u32 iNumber){ *this += C_String(iNumber); return *this;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String& C_String::operator += (const C_String& strToken){ *this += strToken.m_pszBuff; return *this;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String C_String::ToLower() const{ C_String strResult(m_iLength, true); for(unsigned int i = 0; i < m_iLength; i++) strResult.m_pszBuff[i] = tolower(m_pszBuff[i]); strResult.m_pszBuff[m_iLength] = '\0'; return strResult;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String C_String::ToUpper() const{ C_String strResult(m_iLength+1, true); for(unsigned int i = 0; i < m_iLength; i++) strResult.m_pszBuff[i] = toupper(m_pszBuff[i]); strResult.m_pszBuff[m_iLength] = '\0'; return strResult;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String C_String::SubString(unsigned int iBeginning, unsigned int iEnd) const{ ASSERT(iEnd <= m_iLength); ASSERT(iEnd >= iBeginning); unsigned int iLen = iEnd - iBeginning; C_String strResult(iLen, true); memcpy(strResult.m_pszBuff, m_pszBuff+iBeginning, iLen); strResult.m_pszBuff[iLen] = '\0'; return strResult;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String C_String::Strip(const C_String& strInvalidChars) const{ unsigned int iStart = 0; while(iStart < m_iLength) { if(strInvalidChars.Find(m_pszBuff[iStart]) >= 0) iStart++; else break; } unsigned int iEnd = m_iLength; while(iEnd > iStart) { if(strInvalidChars.Find(m_pszBuff[iEnd]) >= 0) iEnd--; else break; } return SubString(iStart, iEnd);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// No check is mode on the validity of the string, so overflows and underflows// are possible//------------------------------------------------------------------------------int C_String::ToInt() const{ // Base is set to 0 so that the strtol function will try to detect it return strtol(m_pszBuff, NULL, 0);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Returns the position of the first occurence of the char if any or GEN_ERR// if not found//------------------------------------------------------------------------------int C_String::Find(char cChar, unsigned int iStart) const{ for(unsigned int iResult = iStart; iResult < m_iLength; iResult++) { if(m_pszBuff[iResult] == cChar) return iResult; } return GEN_ERR;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Returns the position of the first occurence of the substring if any or// GEN_ERR if not found// Build a kind of pseudo automata for the substring lookup //------------------------------------------------------------------------------int C_String::Find(const C_String& strItem, unsigned int iStart/* = 0*/) const{ int iRc = GEN_ERR; // Do those tests now to avoid doing them at each iteration below if(strItem.m_iLength > 0 && iStart + strItem.m_iLength < m_iLength) { const char* pCurrentChar = m_pszBuff; while(*pCurrentChar != '\0') { // We are in state 1: nothing has been found. Try to find the first char // of the item if(strItem.m_pszBuff[0] == pCurrentChar[0]) { // We now are in state 2: remain in this state as long as we found the // end of the item in the string unsigned int i = 1; while(strItem.m_pszBuff[i] == pCurrentChar[i]) i++; // Don't go back to state 1 if the item has not been fully matched if(i >= strItem.m_iLength) { iRc = pCurrentChar - m_pszBuff; break; } } // First char of the item not found: look further in the string pCurrentChar++; } } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Returns true if and only if the string starts with the given item//------------------------------------------------------------------------------bool C_String::StartsWith(const C_String& strItem) const{ bool bResult = false; unsigned int iSize = strItem.Length(); if(m_iLength >= iSize && memcmp(m_pszBuff, strItem.m_pszBuff, iSize) == 0) bResult = true; return bResult;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Returns true if and only if the string ends with the given item//------------------------------------------------------------------------------bool C_String::EndsWith(const C_String& strItem) const{ bool bResult = false; unsigned int iSize = strItem.Length(); char* pszBegin = m_pszBuff + m_iLength - iSize; if(m_iLength >= iSize && memcmp(pszBegin, strItem.m_pszBuff, iSize) == 0) bResult = true; return bResult;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Look at http://ourworld.compuserve.com/homepages/bob_jenkins/doobs.htm// for an explanation of the algorithm//------------------------------------------------------------------------------u32 C_String::GetHashCode() const{ // Mix the bits of 3 u32 integer #define Mix(a,b,c) \ { \ a -= b; a -= c; a ^= (c>>13); \ b -= c; b -= a; b ^= (a<<8); \ c -= a; c -= b; c ^= (b>>13); \ a -= b; a -= c; a ^= (c>>12); \ b -= c; b -= a; b ^= (a<<16); \ c -= a; c -= b; c ^= (b>>5); \ a -= b; a -= c; a ^= (c>>3); \ b -= c; b -= a; b ^= (a<<10); \ c -= a; c -= b; c ^= (b>>15); \ } // Set up the internal state u32 uiLen = m_iLength; u32 uiToken1 = 0x9e3779b9; // the golden ratio; an arbitrary value u32 uiToken2 = uiToken1; u32 uiToken3 = 0; // Just to have a != value char* pszIter = m_pszBuff; // Handle most of the key while (uiLen >= 12) { uiToken1 += (pszIter[0] +((u32)pszIter[1]<<8) + ((u32)pszIter[2]<<16) + ((u32)pszIter[3]<<24)); uiToken2 += (pszIter[4] +((u32)pszIter[5]<<8) + ((u32)pszIter[6]<<16) + ((u32)pszIter[7]<<24)); uiToken3 += (pszIter[8] +((u32)pszIter[9]<<8) + ((u32)pszIter[10]<<16) + ((u32)pszIter[11]<<24)); Mix(uiToken1, uiToken2, uiToken3); pszIter += 12; uiLen -= 12; } // Handle the last 11 bytes uiToken3 += uiLen; if(uiLen >= 11) uiToken3 += ((u32)pszIter[10]<<24); if(uiLen >= 10) uiToken3 += ((u32)pszIter[9]<<16); if(uiLen >= 9) uiToken3 += ((u32)pszIter[8]<<8); // The first byte of c is reserved for the length if(uiLen >= 8) uiToken2 += ((u32)pszIter[7]<<24); if(uiLen >= 7) uiToken2 += ((u32)pszIter[6]<<16); if(uiLen >= 6) uiToken2 += ((u32)pszIter[5]<<8); if(uiLen >= 5) uiToken2 += ((u32)pszIter[4]); if(uiLen >= 4) uiToken1 += ((u32)pszIter[3]<<24); if(uiLen >= 3) uiToken1 += ((u32)pszIter[2]<<16); if(uiLen >= 2) uiToken1 += ((u32)pszIter[1]<<8); if(uiLen >= 1) uiToken1 += ((u32)pszIter[0]); // Case 0: nothing left to add Mix(uiToken1, uiToken2, uiToken3); return uiToken3;}//******************************************************************************// Additional external operators//******************************************************************************// Solve various problems when dealing with traditional strings (char*)// such as this one: "my traditional string" + C_String// To be extended //******************************************************************************//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_String operator + (const char* pszLeft, const C_String& strRight){ C_String strResult(pszLeft); strResult += strRight; return strResult;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_String operator + (const int iLeft, const C_String& strRight){ C_String strResult; strResult += iLeft; strResult += strRight; return strResult;}//******************************************************************************// class C_StringTokenizer//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_StringTokenizer::C_StringTokenizer(const C_String& strSource, char cSep): m_strSource(strSource){ m_cSeparator = cSep; m_iPosition = 0;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_StringTokenizer::SetSeparator(char cSep){ m_cSeparator = cSep;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------bool C_StringTokenizer::HasMoreToken(){ unsigned int iStrLen = m_strSource.Length(); // Skip the initial separators if any while((m_iPosition < iStrLen) && (m_strSource[m_iPosition] == m_cSeparator)) m_iPosition++; // There is a token only if we stopped at least one char before the end // of the string. The test is made on m_iPosition+1 and not on iStrLen-1 // because iStrLen is unsigned return m_iPosition < iStrLen;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_String C_StringTokenizer::NextToken(){ unsigned int iStrLen = m_strSource.Length(); // Skip the initial separators if any while((m_iPosition < iStrLen) && (m_strSource[m_iPosition] == m_cSeparator)) m_iPosition++; unsigned int iStart = m_iPosition; ASSERT(m_iPosition < iStrLen); while((m_iPosition < iStrLen) && (m_strSource[m_iPosition] != m_cSeparator)) { m_iPosition++; } return m_strSource.SubString(iStart, m_iPosition);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_StringTokenizer::Reset(){ m_iPosition = 0;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------unsigned int C_StringTokenizer::CountTokens() const{ unsigned int iResult = 1; unsigned int iStrLen = m_strSource.Length(); for(unsigned int i = m_iPosition; i < iStrLen; i++) { if(m_strSource[i] == m_cSeparator) iResult++; } return iResult;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -