问题描述:
自定义一个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;
}
运行结果: