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

int CString::CreateFromData(const char *data, long len)        //根据data和长度len创建对象
 {
 
 Empty();      //清空
 
    if (len <= 0) 
  return TRUE;
 
    if (data == NULL)
  return TRUE;
 
 // actually, it's impossible
  if (len > m_nSize)
  return FALSE;
 
 // copy data and set length
  memcpy(m_pDataStart, data, len);    //将字符数组复制给m_pDataStart指向内存空间
  m_nLength = len;             
  m_pDataStart[m_nLength] = '\0';     
  m_pDataEnd = &(m_pDataStart[m_nLength]);      //取得尾指针m_pDataEnd
 
 return TRUE;
 }
 

long CString::GetLength(void) const
 {
  return m_nLength;
 }
 

int CString::IsEmpty(void) const
 {
  return !m_nLength;
 }
 

int CString::Grow(int iBufferNum)
 {
  //unsigned char *pNewSpace = NULL;
 
 if (iBufferNum <= 0) 
  return 0;
  AssignNewSpace(m_nSize + iBufferNum * STR_PAGE_SIZE, 1);    //分配新的内存空间,变为原来的两倍,移动1倍
  return 1;
 }
 

int CString::Append(const char *pSrc, int iLen)
 {
  int total_len;
  char *pNewStart = NULL;
 
 if (iLen <= 0)
  return 0;
 
 total_len = m_nLength + iLen;        //append后的总的字符串长度
 
 // if some space avaliable, defrag it firstly.
  if (m_nSize > total_len)            //如果原来总内存空间长度大于append后的字符串长度
  {
  //如果原来剩余空闲空间小于新添加子字符串的长度,而且
  if (m_nSize - (m_pDataEnd - m_pBuffer) < iLen && m_pDataStart - m_pBuffer > 0)  //而且m_pDataStart在m_pBuffer的后面
  {
    Defrag();      //调节原来的字符串
  }
  }
  else                                //如果原来总内存空间长小于append后的字符串长度,需要开辟新空间
  {
  // allocate new memory space and copy orignal data
  AssignNewSpace(total_len + 1, 1);        //分配新的内存空间,变为原来的两倍,移动1倍
  }
 
 // get the merge point
  pNewStart = m_pDataEnd; //将原来字符串的末尾指针转变成新添加子串的开始指针
  if (!pNewStart)
  return 0;
 
 // copy data and adjust some pointers
  memcpy(pNewStart, pSrc, iLen);    //将新添加串pSrc放置在原来串联的末尾
  m_nLength = total_len;            //字符串的总长度变化
  m_pDataStart[m_nLength] = 0;      //新的字符串最后以为置为0
  m_pDataEnd = &(m_pDataStart[m_nLength]);  //让m_pDataEnd指向新的字符串的末尾指针
 
 return 1;
 }
 void CString::Defrag(void)
 {
  // Sure!    重新初始化原来字符串头指针m_pDataStart,指向头部
  memmove(m_pBuffer, m_pDataStart, m_nLength);    //将m_pDataStart复制给m_pBuffer
  // adjust those related pointers
  m_pDataStart = m_pBuffer;                        //m_pDataStart指向m_pBuffer
  m_pDataStart[m_nLength] = 0;                   
  m_pDataEnd = &(m_pDataStart[m_nLength]);          //重新获得原来的字符串尾指针m_pDataEnd 
 }
 
// Append another CString to this one
 
int CString::Append(CString *pNewStr)
 {
  char *pNewStart = NULL, *pSrc = NULL, *pDest = NULL;
 
 int len = pNewStr->GetLength();      //新添加子串的长度
  int total_len;
 
 if (len <= 0)
  return 0;
 
 // const char *
  pSrc = pNewStr->GetData();          //获得要添加的字符串的头指针
  if (!pSrc)
  return 0;
 
 total_len = m_nLength + len;        //新字符串的总长度 = 原来字符串长度 + 添加字符串长度
 
 // if some space avaliable, defrag it firstly.
  if (m_nSize - (m_pDataEnd - m_pBuffer) < len && m_pDataStart - m_pBuffer > 0)
  {
  Defrag();
  }
 
 // allocate new memory space
  AssignNewSpace(total_len + 1, 1);      // //根据total_len分配新的内存空间
  // get the merge point
  pNewStart = m_pDataEnd;                  //将原来字符串的末尾指针转变成新添加子串的开始指针
  if (!pNewStart)
  return 0;
 
 // copy data and adjust some pointers
  memcpy(pNewStart, pSrc, len);          //将新添加串pSrc放置在原来串联的末尾
  m_nLength = total_len;
  m_pDataStart[m_nLength] = 0;
  m_pDataEnd = &(m_pDataStart[m_nLength]);      //让m_pDataEnd指向新的字符串的末尾指针
 
 return 1;
 }
 
// Adjust start and end pointer of its buffer
 
// Get one character at give position
 
char CString::GetAt(int nIndex) const
 {
    if (nIndex >= m_nLength)     
        return -1;
  if (nIndex < 0)
  return -1;
 
 return m_pDataStart[nIndex];   
 }
 
// return single character at zero-based index
 char CString::operator[](int nIndex) const
 {
    if (nIndex >= m_nLength)
        return -1;
 
 return m_pDataStart[nIndex];
 }
 
// return pointer to const string
 CString::operator LPCTSTR() const              //将该字符串转变为const char*字符串常量
 {
  return (const char*)m_pDataStart;
 }
 
// duplicate a string
 CString *CString::Duplicate(int iBufferNum) const
 {
  CString *pCStr = NULL;
 
 pCStr = new CString(m_pDataStart, m_nLength, iBufferNum);
 
  return pCStr;
 }
 
// copy from another CString
 const CString& CString::operator=(CString& stringSrc)      //赋值操作符
 {
  long len = stringSrc.GetLength();      //取得stringSrc字符串长度
 
 if (len >= m_nSize)                    //如果空间大小不够
  {
  AssignNewSpace(len + 1, 0); // don't copy orignal data      //将会申请一块新的内存空间
  }
 
 // copy data and adjust pointers
  Empty();            //清空
  memcpy(m_pDataStart, stringSrc.GetData(), len);      //将字符串stringSrc复制给新的m_pDataStart
    m_pDataStart[len] = 0;
  m_pDataEnd = &(m_pDataStart[len]);                  //获得新的m_pDataEnd
  m_nLength  = len;
 
 return *this;                                   
 }
 
// set string content to single character
 CString &CString::operator=(char c)                            //赋值操作符,将字符赋给字符串
 {
  if (m_nSize < 2) // c + '\0' length                      //如果内存空间不足
  { // it needs to realloc space, but we use new and delete pair
  SafeDestroy();
  m_pBuffer = new char[2];                            //重新申请内存
  m_nSize  = 2;
  //TODO, I don't check the value of this pointer, unkown result. :)
  }
  m_pDataStart = m_pBuffer;                //获得头指针
  m_pDataStart[0] = c;
  m_pDataStart[1] = 0;
  m_pDataEnd = &(m_pDataStart[1]);        //获得尾指针
  m_nLength  = 1;
 
 return *this;
 }
 
// Set one character at give position
 
void CString::SetAt(long pos, char ch)
 {
    if (pos < m_nLength)
        m_pDataStart[pos] = ch;
 
 return;
 }
 
// Get the string started from give position 
 
void CString::GetManyChars(char *buf, long pos, long len) const
 {
  if (buf == NULL)
  return;
 
    if (pos >= m_nLength)
        return;
 
    if (pos + len > m_nLength)
        len = m_nLength - pos;
 
    if (len > 0)
        memcpy(buf, m_pDataStart + pos, len);    //将 m_pDataStart + pos开始长为len的子串复制给buf
 }
 
// Compare itself with a new string, case-sensitive
 
int CString::Compare(const char *pNewStr) const
 {
  if (pNewStr == NULL)
  return -1;
 
 return strcmp(m_pDataStart, pNewStr);     
 }
 
// Compare itself with a new string, case-ignored
 int CString::CompareNoCase(const char *pNewStr) const
 {
  if (pNewStr == NULL)
  return -1;
 
#ifndef WIN32
  return strcasecmp(m_pDataStart, pNewStr);
 #else
  return stricmp(m_pDataStart, pNewStr);
 #endif
 }
 
// find a character start from a give position
 int CString::Find(int ch, long pos) const
 {
    char *p = NULL;
 
    if (ch < 0)
  return -1;
 
    if (ch > UCHAR_MAX)
  return -1;
 
    if (pos < 0)
  return -1;
 
    if (pos >= m_nLength)
        return -1;
 
    p = (char*)memchr(m_pDataStart + pos, ch, m_nLength - pos);
 
    if (!p)
        return -1;
    return p - m_pDataStart;
 }
 
// find a string start from a give position
 int CString::Find(const char *str, long pos) const
 {
    long len;
    char *p = NULL;
 
    if (str == NULL)
  return -1;
 
    len = strlen(str);
 
 
    if (len == 0)
        return 0;
 
 p = (char *)strstr(m_pDataStart + pos, str);
 
 if (p == NULL)
  return -1;
  else
  return p - m_pDataStart;
 }
 
char *CString::GetBuffer(int nMinBufLength)    //获得该字符串头指针,并且说明返回的内存空间最小值
 {
  Defrag();
  if (nMinBufLength > m_nLength)
  AssignNewSpace(nMinBufLength, 1);
  return m_pDataStart;
 }
 
void CString::ReleaseBuffer(int nNewLength)
 {
  return;
 }
 
//Extracts the left part of a string.
 CString CString::Left(int count) const
 {
  if (count < 0)
  count = 0;
  if (count >= m_nLength)
  return *this;
 
 CString dest(m_pDataStart, count);  //调用构造函数新建一个
  return dest;
 }
 
//Extracts the right part of a string.
 CString CString::Right(int count) const
 {
  if (count < 0)
  count = 0;
  if (count >= m_nLength)
  return *this;
 
 CString dest(&(m_pDataStart[m_nLength - count]), count);
  return dest;
 }
 
//Converts all the characters in this string to uppercase characters.
 void CString::MakeUpper(void)
 {
  strupr(m_pDataStart);
 }
 
//Converts all the characters in this string to lowercase characters.
 void CString::MakeLower(void)
 {
  strlwr(m_pDataStart);
 }
 
// TODO: check the space left in the two pading of the whole buffer
 
// trim the left spaces
 void CString::TrimLeft(void)    // //将字符串右边的空格去掉
 {
    int start = 0;
 
    while (isspace(m_pDataStart[start]) && start < m_nLength)
        start ++;
 
    if (start > 0)
  {
  m_pDataStart += start;
  }
 }
 

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

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