自定义CString类

问题描述:

自定义一个CString类,包括获取字符串长度,字符串查找,字符串比较,字符串取子串等都自己来实现。

参考代码:

MyString.h文件

#pragma once

#include <iostream>
#include <assert.h>
#include <stdarg.h>

class CMyString
{
    friend std::ostream& operator<< (std::ostream&os, CMyString& other);//重载输入
    friend std::istream& operator>> (std::istream&in, CMyString& other);//重载输出

public:
    CMyString(const char* str = NULL);//构造函数兼容默认构造函数
    CMyString(const CMyString& other);//拷贝构造函数
    CMyString& operator=(const CMyString& other);//重载=
    CMyString operator+(const CMyString& other);//重载+
    CMyString operator+=(const CMyString& other);//重载+=
    ~CMyString();//析构函数
    size_t GetLength();//获取字符串长度
    bool operator==(const CMyString& other);//判断两个字符串是否相等
    char& operator[](unsigned int nIndex);//重载[]
    const char* GetC_Str() const;//获取C字符串
    void MakeUpper();//转为大写
    void MakeLower();//转为小写
    bool IsEmpty();//判断字符串是否为空
    void Empty();//清空字符串
    void Format(char* fmt, ...);//格式化字符串
    int CompareNoCase(const CMyString& other);//不区分大小写比较字符串,大于other返回1,小于返回-1,等于返回0
    int CompareNoCase(const char* str);//重载不区分大小写的比较函数
    CMyString LeftSubString(int nCount);//取子串,从左边开始取nCount个字符
    CMyString RightSubString(int nCount);//取子串,从右边往左边数nCount个字符
    CMyString MidSubString(int nFirst, int nCount);//取子串,从nFirst的位置开始,取nCount个字符
    CMyString MidSubString(int nFirst);//重载取子串,从nFirst的位置开始,一直取到最后
    int FindString(const CMyString& other);//查找子串
    int FindString(const char* str);//重载查找子串
    int FindString(const CMyString& other, int nStart);//从nStart位置开始查找子串
    int FindString(const char* str, int nStart);//重载从nStart位置开始查找子串
    int FindChar(char ch);//查找字符
    int FindChar(char ch, int nStart);//从nStart的位置开始查找字符
    void MakeReverse();//字符串逆置
    int Remove(char ch);//删除字符串中所有的指定字符
    int Replace(char chOld, char chNew);//替换字符
    int Replace(char* pOld, char* pNew);//替换字符串
    int Insert(int nIndex, char ch);//在nIndex位置插入一个字符
    int Insert(int nIndex, char* pStr);//在nIndex位置插入一个字符串
    void Sort();//对字符串进行排序
    int ToInt();//把字符串转成int类型

private:
    size_t MyStrlen(const char *pStr);
    char * MyStrcpy(char *dst, const char *src);
    char * MyStrcat(char *dst, const char *src);
    int MyStrcmp(const char* str1, const char* str2);
    char *ReturnUpper(const char* str);
    char *ReturnLower(const char* str);
    char* GetSubstring(const char *strSource, const unsigned int uStartPos, const unsigned int uEndPos);
    int MyStrstr(const char *s1, const char *s2, int nStartPos = 0);
    int MyIsSpace(char ch);
    int MyIsDigit(char ch);
    int MyAtoi(const char* pStr);

private:
    char *m_str;
    size_t m_nLength;
};

MyString.cpp文件

#include "StdAfx.h"
#include "MyString.h"

CMyString::CMyString(const char* str /*= NULL*/)
{
    if (NULL == str)
    {
        m_nLength = 0;
        m_str = new char[1];
        *m_str = '\0';
    }
    else
    {
        m_nLength = MyStrlen(str);
        m_str = new char[m_nLength + 1];
        MyStrcpy(m_str, str);
    }
}

CMyString::CMyString(const CMyString& other)
{
    m_nLength = other.m_nLength;
    m_str = new char[m_nLength + 1];
    MyStrcpy(m_str, other.m_str);
}

CMyString& CMyString::operator=(const CMyString& other)
{
    if (this == &other)
        return *this;

    delete []m_str;
    m_nLength = other.m_nLength;
    m_str = new char[m_nLength + 1];
    MyStrcpy(m_str, other.m_str);
    return *this;
}

CMyString CMyString::operator+(const CMyString& other)
{
    CMyString retStr;
    retStr.m_nLength = m_nLength + other.m_nLength;
    retStr.m_str = new char[retStr.GetLength() + 1];
    MyStrcpy(retStr.m_str, m_str);
    MyStrcat(retStr.m_str, other.m_str);
    return retStr;
}

CMyString CMyString::operator+=(const CMyString& other)
{
    m_nLength += other.m_nLength;
    char *temp = new char[m_nLength + 1];
    MyStrcpy(temp, m_str);
    MyStrcat(temp, other.m_str);
    delete []m_str;
    m_str = temp;
    return *this;
}

CMyString::~CMyString()
{
    delete []m_str;
    m_nLength = 0;
}

size_t CMyString::GetLength()
{
    return m_nLength;
}

bool CMyString::operator==(const CMyString& other)
{
    if (other.m_nLength != m_nLength)
        return false;

    return MyStrcmp(m_str, other.m_str) ? false : true;
}

char& CMyString::operator[](unsigned int nIndex)
{
    assert(nIndex >= 0 && nIndex <= m_nLength - 1);

    return m_str[nIndex];
}

const char* CMyString::GetC_Str() const
{
    return m_str;
}

size_t CMyString::MyStrlen(const char *pStr)
{
    size_t nLen = 0;
    if (NULL == pStr)
        return 0;

    while (*pStr++ != '\0')
        nLen++;

    return nLen;
}

char * CMyString::MyStrcpy(char *dst, const char *src)
{
    if (dst == NULL || src == NULL)
        return NULL;

    if (dst == src)
        return dst;

    char *ret = dst;
    int nLen = MyStrlen(src);
    dst = dst + nLen;
    src = src + nLen;
    int nLoop = nLen + 1;
    while (nLoop--)
    {
        *dst = *src;
        src--;
        dst--;
    }

    return ret;
}

char * CMyString::MyStrcat(char *dst, const char *src)
{
    assert(dst != NULL && src != NULL);
    char *temp = dst;
    while (*temp != '\0')
        temp++;
    while ((*temp++ = *src++) != '\0');

    return dst;
}

void CMyString::MakeUpper()
{
    for (int i = 0; i < m_nLength; i++)
    {
        if (m_str[i] >= 'a' && m_str[i] <= 'z')
        {
            m_str[i] -= 'a' - 'A';
        }
    }
}

void CMyString::MakeLower()
{
    for (int i = 0; i < m_nLength; i++)
    {
        if (m_str[i] >= 'A' && m_str[i] <= 'Z')
        {
            m_str[i] += 'a' - 'A';
        }
    }
}

bool CMyString::IsEmpty()
{
    return 0 == m_nLength;
}

void CMyString::Empty()
{
    delete []m_str;
    m_nLength = 0;
    m_str = new char[1];
    *m_str = '\0';
}

void CMyString::Format(char* fmt, ...)
{
    static const int nBufferSize = 4 * 1024;
    char TmpBuffer[nBufferSize] = {0};
    va_list argList;
    va_start(argList, fmt);
    vsnprintf(TmpBuffer, nBufferSize, fmt, argList);
    va_end(argList);

    delete []m_str;
    m_str = new char[nBufferSize];
    MyStrcpy(m_str, TmpBuffer);
    m_nLength = MyStrlen(m_str);
}

int CMyString::MyStrcmp(const char* str1, const char* str2)
{
    assert(NULL != str1 && NULL != str2);
    while (*str1 && *str2 && (*str1 == *str2))
    {
        str1++;
        str2++;
    }
    return *str1 - *str2;
}

int CMyString::CompareNoCase(const CMyString& other)
{
    char *str1 = ReturnLower(m_str);
    char *str2 = ReturnLower(other.m_str);
    int nRet = MyStrcmp(str1, str2);
    delete []str1;
    delete []str2;
    if (nRet > 0)
        return 1;
    else if (nRet < 0)
        return -1;

    return 0;
}

int CMyString::CompareNoCase(const char* str)
{
    char *str1 = ReturnLower(m_str);
    char *str2 = ReturnLower(str);
    int nRet = MyStrcmp(str1, str2);
    delete []str1;
    delete []str2;
    if (nRet > 0)
        return 1;
    else if (nRet < 0)
        return -1;

    return 0;
}

char * CMyString::ReturnUpper(const char* str)
{
    int nLen = MyStrlen(str);
    char *Temp = new char[nLen + 1];
    MyStrcpy(Temp, str);

    for (int i = 0; i < nLen; i++)
    {
        if (Temp[i] >= 'a' && Temp[i] <= 'z')
        {
            Temp[i] -= 'a' - 'A';
        }
    }
    return Temp;
}

char * CMyString::ReturnLower(const char* str)
{
    int nLen = MyStrlen(str);
    char *Temp = new char[nLen + 1];
    MyStrcpy(Temp, str);

    for (int i = 0; i < nLen; i++)
    {
        if (Temp[i] >= 'a' && Temp[i] <= 'z')
        {
            Temp[i] -= 'a' - 'A';
        }
    }
    return Temp;
}

CMyString CMyString::LeftSubString(int nCount)
{
    if (nCount < 0)
        nCount = 0;

    if (nCount >= m_nLength)
        return *this;


    char *pTemp = GetSubstring(m_str, 0, nCount - 1);
    CMyString strTemp(pTemp);
    delete []pTemp;
    return strTemp;
}

CMyString CMyString::RightSubString(int nCount)
{
    if (nCount < 0)
        nCount = 0;

    if (nCount >= m_nLength)
        return *this;

    char *pTemp = GetSubstring(m_str, m_nLength - nCount, m_nLength - 1);
    CMyString strTemp(pTemp);
    delete []pTemp;
    return strTemp;
}

CMyString CMyString::MidSubString(int nFirst, int nCount)
{
    if (nFirst < 0)
        nFirst = 0;

    if (nFirst >= m_nLength)
        nFirst = m_nLength - 1;

    int nEndPos = nFirst + nCount - 1;
    if (nEndPos < nFirst)
        nEndPos = nFirst;

    if (nEndPos >= m_nLength)
        nEndPos = m_nLength - 1;
    char *pTemp = GetSubstring(m_str, nFirst, nEndPos);
    CMyString strTemp(pTemp);
    delete []pTemp;
    return strTemp;
}

CMyString CMyString::MidSubString(int nFirst)
{
    if (nFirst < 0)
        nFirst = 0;

    if (nFirst >= m_nLength)
        nFirst = m_nLength - 1;

    char *pTemp = GetSubstring(m_str, nFirst, m_nLength - 1);
    CMyString strTemp(pTemp);
    delete []pTemp;
    return strTemp;
}

char* CMyString::GetSubstring(const char *strSource, const unsigned int uStartPos, const unsigned int uEndPos)
{
    unsigned int uLen = MyStrlen(strSource);  
    if (uLen == 0)  
    {  
        return "";  
    }  
    char *strTemp = new char[uLen + 1];
    memset(strTemp, 0, uLen + 1);  
    strcpy(strTemp, strSource);  

    if(uStartPos > uLen)  
    {  
        delete []strTemp;
        return "";  
    }  

    uLen = uEndPos - uStartPos + 1;
    char *strSub = new char[uLen + 1];
    memset(strSub, 0, uLen+1);  

    unsigned int i;
    for(i = 0; i < uLen; i++)  
    {  
        strSub[i] = strTemp[uStartPos + i];  
    }  
    strSub[i] = '\0';  

    delete []strTemp; 

    return strSub;
}

int CMyString::MyStrstr(const char *s1, const char *s2, int nStartPos)
{
    size_t l1, l2; 
    l2 = MyStrlen(s2);
    if (!l2)
        return nStartPos;

    int nPos = 0;
    l1 = MyStrlen(s1);
    while (l1 >= l2) 
    {
        l1--;
        if (!memcmp(s1, s2, l2))
            return nStartPos + nPos;
        s1++;
        nPos++;
    }

    return -1;
}

int CMyString::FindString(const CMyString& other)
{
    return MyStrstr(m_str, other.m_str);
}

int CMyString::FindString(const char* str)
{
    return MyStrstr(m_str, str);
}

int CMyString::FindString(const CMyString& other, int nStart)
{
    return MyStrstr(m_str + nStart, other.m_str, nStart);
}

int CMyString::FindString(const char* str, int nStart)
{
    return MyStrstr(m_str + nStart, str, nStart);
}

int CMyString::FindChar(char ch)
{
    for (int i = 0; i < m_nLength; i++)
    {
        if (m_str[i] == ch)
            return i;
    }
    return -1;
}

int CMyString::FindChar(char ch, int nStart)
{
    for (int i = nStart; i < m_nLength; i++)
    {
        if (m_str[i] == ch)
            return i;
    }
    return -1;
}

void CMyString::MakeReverse()
{
    for (int i = 0; i < m_nLength / 2; i++)
    {
        char ch = m_str[i];
        m_str[i] = m_str[m_nLength - 1 - i];
        m_str[m_nLength - 1 - i] = ch;
    }
}

int CMyString::Remove(char ch)
{
    int nNewLen = 0;//删除后的长度
    for (int i = 0; i < m_nLength; i++)
    {
        if (m_str[i] != ch)
            m_str[nNewLen++] = m_str[i];
    }
    m_str[nNewLen] = '\0';
    int nDeleteCount = m_nLength - nNewLen;
    m_nLength = nNewLen;
    return nDeleteCount;
}

int CMyString::Replace(char chOld, char chNew)
{
    int nCount = 0;
    for (int i = 0; i < m_nLength; i++)
    {
        if (m_str[i] == chOld)
        {
            m_str[i] = chNew;
            nCount++;
        }
    }
    return nCount;
}

int CMyString::Replace(char* pOld, char* pNew)
{
    int nOldLen = MyStrlen(pOld);
    int nNewLen = MyStrlen(pNew);
    int nPos = 0;
    while (1)
    {
        nPos = MyStrstr(m_str + nPos,  pOld, nPos);
        if (-1 == nPos)
            break;

        char *pTemp = new char[m_nLength + nNewLen + 1];
        memset(pTemp, 0, m_nLength + nNewLen + 1);

        char *pSub1 = NULL;
        if (nPos >= 1)
        {
            pSub1 = GetSubstring(m_str, 0, nPos - 1);
            MyStrcpy(pTemp, pSub1);
            delete []pSub1;
        }

        MyStrcat(pTemp, pNew);

        pSub1 = GetSubstring(m_str, nPos + nOldLen, m_nLength - 1);
        MyStrcat(pTemp, pSub1);
        delete []pSub1;

        delete []m_str;

        nPos += nNewLen;

        m_str = pTemp;
        m_nLength = MyStrlen(pTemp);

    }
    return 0;
}

int CMyString::Insert(int nIndex, char ch)
{
    char *pTemp = new char[m_nLength + 2];
    memset(pTemp, 0, m_nLength + 2);

    char *pSub1 = NULL;
    if (nIndex >= 1)
    {
        pSub1 = GetSubstring(m_str, 0, nIndex - 1);
        MyStrcpy(pTemp, pSub1);
        delete []pSub1;
    }

    pTemp[nIndex] = ch;

    pSub1 = GetSubstring(m_str, nIndex, m_nLength - 1);
    MyStrcat(pTemp, pSub1);
    delete []pSub1;

    delete []m_str;

    m_str = pTemp;
    m_nLength = MyStrlen(pTemp);

    return m_nLength;
}

int CMyString::Insert(int nIndex, char* pStr)
{
    int nInsertLen = MyStrlen(pStr);
    char *pTemp = new char[m_nLength + nInsertLen + 1];
    memset(pTemp, 0, m_nLength + nInsertLen + 1);

    char *pSub1 = NULL;
    if (nIndex >= 1)
    {
        pSub1 = GetSubstring(m_str, 0, nIndex - 1);
        MyStrcpy(pTemp, pSub1);
        delete []pSub1;
    }

    MyStrcat(pTemp, pStr);

    pSub1 = GetSubstring(m_str, nIndex, m_nLength - 1);
    MyStrcat(pTemp, pSub1);
    delete []pSub1;

    delete []m_str;

    m_str = pTemp;
    m_nLength = MyStrlen(pTemp);

    return m_nLength;
}

void CMyString::Sort()
{
    for (int i = 0; i < m_nLength; i++)
    {
        for (int j = i + 1; j < m_nLength; j++)
        {
            if (m_str[i] > m_str[j])
            {
                char ch = m_str[i];
                m_str[i] = m_str[j];
                m_str[j] = ch;
            }
        }
    }
}

int CMyString::MyIsSpace(char ch)
{
    if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\f' || ch == '\v' || ch == '\r')
        return 1;
    return 0;
}

int CMyString::MyIsDigit(char ch)
{
    if (ch >= '0' && ch <= '9')
        return 1;
    return 0;
}

int CMyString::MyAtoi(const char* pStr)
{
    char sign;
    int nValue = 0;
    while (MyIsSpace(*pStr))//去掉空字符
        pStr++;

    sign = *pStr;
    if (sign == '-' || sign == '+')
        pStr++;

    while (MyIsDigit(*pStr))
    {
        nValue = 10 * nValue + (*pStr - '0');
        pStr++;
    }

    return sign == '-' ? -nValue : nValue;
}

int CMyString::ToInt()
{
    return MyAtoi(m_str);
}

std::ostream& operator<<(std::ostream& os, CMyString& other)
{
    os << other.m_str;
    return os;
}

std::istream& operator>>(std::istream& in, CMyString& other)
{
    char temp[1024];
    in >> temp;
    other = temp;
    return in;
}

main.cpp文件进行测试:

// MyString.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MyString.h"

int _tmain(int argc, _TCHAR* argv[])
{
    CMyString str1 = "13579abcdafd";
    CMyString str2 = "abcD";
    CMyString str3 = str1 + str2;
    CMyString str4;
    str4.Format("%s|%s", str1.GetC_Str(), str2.GetC_Str());

    CMyString str5 = "a1b2c3d4att";
    str5.MakeUpper();

    CMyString str6 = "AZab12345";
    str6.MakeLower();


    int nPos = 0;
    while (1)
    {
        nPos = str1.FindChar('d', nPos);
        if (-1 == nPos)
            break;

        printf("nPos=%d\n", nPos);

        nPos++;
    }
    std::cout << str1.ToInt() << std::endl;
    std::cout << str1.FindString("dc") << std::endl;
    std::cout << str1.LeftSubString(4) << std::endl;
    std::cout << str1.RightSubString(4) << std::endl;
    std::cout << str1.MidSubString(1, 4) << std::endl;
    std::cout << str1.MidSubString(1) << std::endl;
    std::cout << str1.CompareNoCase("abcd") << std::endl;
    std::cout << str3.IsEmpty() << std::endl;
    std::cout << str1 << " " << str1.GetLength() << std::endl;
    std::cout << str2 << " " << str2.GetLength() << std::endl;
    std::cout << str3 << " " << str3.GetLength() << std::endl;
    std::cout << str4 << std::endl;
    std::cout << str5 << std::endl;
    str5.Replace("A", "zz");
    std::cout << str5 << std::endl;
    std::cout << str6 << " " << str6.GetLength() << std::endl;
    str6.MakeReverse();
    std::cout << str6 << " " << str6.GetLength() << std::endl;
    str6.Remove('a');
    std::cout << str6 << " " << str6.GetLength() << std::endl;
    str6.Insert(0, 'x');
    std::cout << str6 << " " << str6.GetLength() << std::endl;
    str6.Insert(0, "_+_+_+_+");
    std::cout << str6 << " " << str6.GetLength() << std::endl;
    str6.Sort();
    std::cout << str6 << " " << str6.GetLength() << std::endl;
    return 0;
}

运行结果:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/yi_ming_he/article/details/75000397