标准C++实现字符串类CString(4)

int CString::Replace(const char *lpszOld, const char *lpszNew)
 {
  // can't have empty or NULL lpszOld
  if (!lpszOld)
  return 0;
  int nOldLen = strlen(lpszOld);      //获得旧字符串的长度
  if (nOldLen <= 0)
  return 0;
  int nNewLen = strlen(lpszNew);        //获得新字符串的长度
 
  // loop once to figure out the size of the result string
  int nCount = 0;
  char *lpszStart = m_pDataStart;                 
  char *lpszEnd = m_pDataEnd;
  char *lpszTarget;
  while (lpszStart < lpszEnd)                  //循环处理原有字符串
  {
  while ((lpszTarget = strstr(lpszStart, lpszOld)) != NULL)    //如果在字符串lpszStart中发现子串lpszOld
  {
    nCount++;                                          //子串数量+1
    lpszStart = lpszTarget + nOldLen;                    //往后定位字符串lpszStart,从第一个子串后开始
  }
  lpszStart += strlen(lpszStart) + 1;                    //往后查找
  }
 
 // if any changes were made, make them
  if (nCount > 0)                                      //如果有重复的字符串
  {
  // allocate a new buffer (slow but sure)
  int nNewLength =  m_nLength + (nNewLen - nOldLen) * nCount;  //覆盖后总字符串的大小
  AssignNewSpace(nNewLength + 1, 1);                        //为新的字符串分配内存空间
  // then we just do it in-place
  lpszStart = m_pDataStart;                                //重新初始化m_pDataStart,lpszStart,lpszEnd
  lpszEnd = m_pDataEnd;
 
  // loop again to actually do the work
  while (lpszStart < lpszEnd)                              //循环处理原来的字符串
  {
    while ( (lpszTarget = strstr(lpszStart, lpszOld)) != NULL)        //如果在字符串lpszStart中发现子串lpszOld
    {
    int nBalance = lpszEnd - (lpszTarget + nOldLen);            //字符串lpszTarget后面的字符数量
    memmove(lpszTarget + nNewLen, lpszTarget + nOldLen,
      nBalance * sizeof(char));    //移走lpszTarget原来的字符串,并为lpszTarget重新设置为nNewLen大小内存
    memcpy(lpszTarget, lpszNew, nNewLen * sizeof(char));  //将新字符串lpszNew覆盖旧的子串lpszTarget
    lpszStart = lpszTarget + nNewLen;                    //寻找目标字符串后移nNewLen
    lpszStart[nBalance] = '\0';
    }
    lpszStart += strlen(lpszStart) + 1;      //寻找目标字符串往后走
  }
  m_nLength = nNewLength;                     
  }
 
 return nCount;
 }
 
// format a string
 void CString::Format(char *fmt, ...)
 {
  char TmpBuffer[STR_PAGE_SIZE]; // TODO, should calculate this size dynamically.
 
 va_list argList;
  va_start(argList, fmt);
 #ifdef WIN32
  _vsnprintf(TmpBuffer, STR_PAGE_SIZE, fmt, argList); // just not overwrite something
 #else
  vsnprintf(TmpBuffer, STR_PAGE_SIZE, fmt, argList); // just not overwrite something
 #endif
  va_end(argList);
 }
 
// copy string content from ANSI string (converts to TCHAR)
 const CString& CString::operator=(const char *lpsz)
 {
  int len = strlen(lpsz);
 
 if (m_nSize < len) // c + '\0' length
  { // it needs to realloc space, but we use new and delete pair
  SafeDestroy();
  m_pBuffer = new char[len + 1];
  m_nSize  = len + 1;
  //TODO, I don't check the value of this pointer, unkown result. :)
  }
  m_pDataStart = m_pBuffer;
  strcpy((char *)m_pDataStart, lpsz);
  m_pDataStart[len] = 0;
  m_pDataEnd = &(m_pDataStart[len]);
  m_nLength = len;
 
 return *this;
 }
 
// concatenate a UNICODE character after converting it to TCHAR
 const CString& CString::operator+=(const char *lpsz)
 {
  int len = strlen(lpsz);
 
 if (m_nSize < m_nLength + len + 1)
  {
  AssignNewSpace(m_nLength + len + 1, 1); // allocate new space and move orignal data
  }
  Defrag();
  memcpy(m_pDataEnd, lpsz, len);
  m_pDataEnd += len;
  *m_pDataEnd = 0;
 
 return *this;
 }
 
// concatenate a single character
 const CString& CString::operator+=(char ch)
 {
  if (m_nSize < m_nLength + 1 + 1)
  {
  AssignNewSpace(m_nLength + 1 + 1, 1); // allocate new space and move orignal data
  }
  Defrag();
  memcpy(m_pDataEnd, &ch, 1);
  m_pDataEnd += 1;
  *m_pDataEnd = 0;
 
 return *this;
 }
 
// concatenate from another CString
 const CString& CString::operator+=(CString& string)
 {
  if (m_nSize < m_nLength + string.GetLength() + 1)
  {
  AssignNewSpace(m_nLength + string.GetLength() + 1, 1); // allocate new space and move orignal data
  }
  Defrag();
  memcpy(m_pDataEnd, string.GetData(), string.GetLength());
  m_pDataEnd += string.GetLength();
  *m_pDataEnd = 0;
 
 return *this;
 }
 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/987761179eb0962ebeff51d44e8e322f.html