别人的string的实现,有时间好好学习下

///////////////////////////////////////
//
//          文件名: MyString.h
//            作者: Carrie Chen
//           日期: 2007年11月17日
//            用途: CString类源程序
//      开发平台: VC++2005
//
///////////////////////////////////////

#include <string>
#include <stdlib.h>
#include <iostream>
#include <exception>
#include <string.h>
using namespace std;

enum eErrorType{outOfMemory,indexError};

class CString
{
private:
   char *str;   //指向动态申请的串的指针
   //串长度包括NULL字符,这就意味着哪怕是空字符串,其字符串的大小也为1,而不是0
   //size_t就是无符号整数
   size_t size;        

   //错误报告函数
   void Error(eErrorType errorType)const;

public:

   //构造函数
   CString(char *s="");
   CString(const CString &s);
   //析构函数
   ~CString(void);
   //print()函数本身没有什么实际意义,只是我在编写程序方便测试
   //print()返回的就是实体中的字符串与字符串长度
   //因为我是最后才去写'<<'的重载的
   void print();
  
   //赋值运算符
   //String=String
   void operator=(const CString &s);
   void operator=(char *s);

   //关系运算符
   //String==String
   int operator==(const CString &s)const;
   int operator==(char *s)const;
   friend int operator==(char *str,const CString &s) ;

   //String!=String
   int operator!=(const CString &s)const;
   int operator!=(char *s)const;
   friend int operator!=(char *str,const CString &s);

   //String<=String
   int operator<=(const CString &s)const;
   int operator<=(char *s)const;
   friend int operator<=(char *str,const CString &s);

   //String>=String
   int operator>=(const CString &s)const;
   int operator>=(char *s)const;
   friend int operator>=(char *str,const CString &s);
  
   //String+String
   CString operator+(const CString &s);
   CString operator+(const char *s);
   friend CString operator+(const char *str,const CString &s);
   void operator+=(const CString &s);
   void operator+=(const char *s);
  
   //有关串函数
   //从Start位置开始找首次出现的字符c
   int Find(char c,int start)const;
   ////找字符c最后一次出现的位置
   int FindLast(char c)const;

   //取子串
   CString Substr(int index,int count)const;
   //往String中插入另一个String
   void Insert(const CString &s,int index);
   //插入char
   void Insert(char *s,int index);
   //删除子串
   void Remove(int index,int count);
  
   //String的下标运算
   //为了能让实体更像一个数组,所以我们有必要去重载[]
   //重载,我们就也可以通过s[1]去访部实体中的字符元素了
   char& operator[](int n);
  
  
   //String的输入/输出
   friend ostream& operator<<(ostream& ostr,const CString &s);
   friend istream& operator>>(istream& ostr,const CString &s);

   //读入字符直到结束符
   int ReadString(istream & is=cin,char delimiter='\n');

   //其它函数
   int Length(void)const;
   int IsEmpty(void)const;
   void Clear(void);
};

void CString::print()
{
cout<<str<<endl;
cout<<size<<endl;
}

//错误消息提示
void CString::Error(eErrorType errorType) const
{
switch(errorType)
{
   case outOfMemory:
    cerr<<"Out Of Memory!"<<endl; break;
   case indexError:
    cerr<<"Index Error!"<<endl; break;
}
exit(1);
}


//构造函数。
CString::CString(char *s)
{

size=strlen(s)+1; //长度中包括NULL字符

//为串及NULL字符申请空间并将s拷入
try{
   str=new char[size];
   //若申请失败,则退出程序
   }
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(str,size,s);
}

CString::CString(const CString & s)
{
//长度中包括NULL字符
size=strlen(s.str)+1;
//为串及NULL字符申请空间并将s拷入
str=new char[size];
//若申请失败,则退出程序
try{
   str=new char[size];
   //若申请失败,则退出程序
   }
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(str,size,s.str);
}


//String=String
void CString::operator =(const CString &s)
{
//若大小不符,则删除当前串,并重新申请内存
if(s.size!=size)
{
   delete []str;
   try
   {
    str=new char[s.size];
    strcpy_s(str,s.size,s.str);
   }
   catch(exception e)
   {
    Error(outOfMemory);
   }
   //将其size值赋值为s的size值
   size=s.size;
}
  
}
void CString::operator =(char *s)
{
//若大小不符,则删除当前串,并重新申请内存
if(strlen(s)!=size)
{
   delete []str;
   try
   {
    str=new char[strlen(s)+1];
    strcpy_s(str,strlen(s)+1,s);
   }
   catch(exception e)
   {
    Error(outOfMemory);
   }
   //将其size值赋值为s的size值
   size=strlen(s)+1;
}
}
//String==String
//返回值等于1说明两个字符串相等
int operator==(char *str,const CString &s)
{
return strcmp(str,s.str)==0;
}
int CString::operator ==(char *s) const
{
return strcmp(str,s)==0;
}
int CString::operator ==(const CString &s) const
{
return strcmp(str,s.str)==0;
}


//String!=String
//返回值等于1说明两个字符串不相等
int CString::operator !=(char *s) const
{
return strcmp(str,s)!=0;
}
int CString::operator !=(const CString &s) const
{
return strcmp(str,s.str)!=0;
}
int operator!=(char *str,const CString &s)
{
return strcmp(str,s.str)!=0;
}

//String<=String
//返回值等于1说明两个字符串不相等
int CString::operator <=(char *s) const
{
return strcmp(str,s)<0;
}
int CString::operator <=(const CString &s) const
{
return strcmp(str,s.str)<0;
}
int operator<=(char *str,const CString &s)
{
return strcmp(str,s.str)<0;
}

//String>=String
//返回值等于1说明两个字符串不相等
int CString::operator >=(const CString &s)const
{
return strcmp(str,s.str)>0;
}
int CString::operator >=(char *s) const
{
return strcmp(str,s)>0;
}
int operator>=(char *str,const CString &s)
{
return strcmp(str,s.str)>0;
}


//String+String
CString CString::operator +(const CString &s)
{

//在temp中建立一个长度为len的新串
CString temp;
size_t len;
//删除定义temp时产生的NULL串
delete []temp.str;
//计算拼接后的串长度并为之申请内存
len=size+s.size-1; //只有一个NULL结尾
try
{
   temp.str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(temp.str,size,str); //拷贝str到temp;
strcat_s(temp.str,len,s.str); //连接s.str
temp.size=len;

return temp;  
}
CString CString::operator +(const char *s)
{

CString temp;
size_t len;
delete []temp.str;
len=size+strlen(s);
try
{
   temp.str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(temp.str,size,str);
strcat_s(temp.str,len,s);
temp.size=len;

return temp;
}
CString operator+(const char *str,const CString &s)
{
CString temp;
size_t len;
delete []temp.str;
len=s.size+strlen(str);
try
{
   temp.str=new char[len];
}
catch(exception e)
{
   s.Error(outOfMemory); //友元函数只能访问数据成员,不能访问私有函数
}
strcpy_s(temp.str,strlen(str)+1,str);
strcat_s(temp.str,len,s.str);
temp.size=len;

return temp;
}
void CString::operator+=(const CString &s)
{
char *temp;
temp=new char[size];
strcpy_s(temp,size,str);
delete []str;
size_t len;
len=strlen(temp)+s.size;
try
{
   str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(str,size+1,temp);
strcat_s(str,len,s.str);
size=len;

}
void CString::operator +=(const char *s)
{
char *temp;
temp=new char[size];
strcpy_s(temp,size,str);
delete []str;
size_t len;
len=strlen(temp)+strlen(s)+1;
try
{
   str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(str,size+1,temp);
strcat_s(str,len,s);
size=len;
}

//从Start位置开始找首次出现的字符c
//返回字符c所在的位置
int CString::Find(char c,int start)const
{
int ret;
//判断start的有效性
if(start<0||start>int(size-1))
   Error(indexError);
  
char *p;
p=str;
p=p+start;
ret=start;
  
while(*p!=NULL)
{

   if(*p==c) return ret;
   else
   {
    p++;
    ret++;
   }
}

return ret=-1;

}
//返回字符c在串中的最后位置
//返回字符c所在的位置
int CString::FindLast(char c) const
{
int ret;
char *p;
//用c++库函数strchr。返回该字符在串中最后位置的指针
p=strrchr(str,c);
if(p!=NULL)
   ret=int(p-str); //计算下标
else
   ret=-1;
return ret;
}

//返回从index开始共count个字符的子串
CString CString::Substr(int index, int count) const
{
//从index到串尾的字符个数
int charsLeft=int(size-index-1),i;
//建立子串temp;
CString temp;
char *p,*q;
/*若index越界,返回空串*/
if(index>=int(size-1))
   return temp;
if(index<0||count<0)
   Error(indexError);
/*若count>剩下的字符,则只用剩下的字符*/
if(count>charsLeft)
   count=charsLeft;
/*删除定义temp时产生的空串*/
delete[] temp.str;
/*为子串申请动态内存*/
try
{
   temp.str=new char[count+1];
}
catch(exception e)
{
   Error(outOfMemory);
}
/*从str中拷贝count个字符到temp.str;*/
for(i=0,p=temp.str,q=&str[index];i<count;i++)
   *p++=*q++;
/*用NULL结束该串*/
*p=0;
temp.size=count+1;
return temp;
}

//往String中插入另一个String
void CString::Insert(const CString &s,int index)
{
//检验index的有效性
if(index<0||index>=int(size-1))
   Error(indexError);
//将原来的str寄存在temp中
CString temp;
delete []temp.str;
temp.str=new char[size];
strcpy_s(temp.str,size,str);
temp.size=size;
//获取剩下字符串
char *p;
    size_t leftsize=size-index-1;
p=new char[leftsize];
strcpy_s(p,leftsize,str+index+1);
  
size_t len;
len=s.size+temp.size-1;
delete []str;
try
{
   str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(str,temp.size,temp.str);

//截掉后半段字符
str[index+1]=NULL;
//插入字符串
strcat_s(str,len,s.str);
strcat_s(str,len,p);
size=len;

}
void CString::Insert(char *s,int index)
{
//检验index的有效性
if(index<0||index>=int(size-1))
   Error(indexError);
//将原来的str寄存在temp中
CString temp;
delete []temp.str;
temp.str=new char[size];
strcpy_s(temp.str,size,str);
temp.size=size;


//获取剩下字符串
char *p;
    size_t leftsize=size-index-1;
p=new char[leftsize];
strcpy_s(p,leftsize,str+index+1);
  
size_t len;
len=strlen(s)+temp.size;
delete []str;
try
{
   str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
strcpy_s(str,temp.size,temp.str);
  
//截掉后半段字符
str[index+1]=NULL;

//插入字符串
strcat_s(str,len,s);
strcat_s(str,len,p);
size=len;
}
//删除子串
void CString::Remove(int index,int count)
{
//检验index,count的有效性
if(index<0||index>=int(size-1)||count<0)
   Error(indexError);
//如果count大于所剩下字符串个数,则按剩下的字符串个数算
if(count>int(size-index-1))
   count=(int)size-index-1;

//获取剩下字符串
char *p;
    size_t leftsize=size-index-1;
p=new char[leftsize];
strcpy_s(p,leftsize,str+index+count);

//截掉后半段字符
str[index]=NULL;
//q寄存前半段字符
    char *q=new char[strlen(str)+1];
strcpy_s(q,strlen(str)+1,str);

size_t len;
len=strlen(q)+strlen(p)+1;
delete []str;
try
{
   str=new char[len];
}
catch(exception e)
{
   Error(outOfMemory);
}
//重新组合字符串
strcpy_s(str,len,q);
strcat_s(str,len,p);

size=len;
}

//String的下标运算
char& CString::operator[](int n)
{
return str[n];
}
//String的输入/输出
ostream& operator<<(ostream& ostr,const CString &s)
{
ostr<<s.str;
return ostr;
}

istream& operator>>(istream& ostr,const CString &s)
{
char temp[256];
str.getline(temp, 256);
delete []s.str;
s.size = strlen(temp)+1;
   s.str = new char[s.size];
assert(s.str!=NULL);
strcpy_s(s.str,s.size,temp);
return istr;
}

//从流istr中读入一行文本
int CString::ReadString(std::istream &istr, char delimiter)
{
//读入一行到tmp中
char tmp[256];
//文件未结束,读入最多255个字符的一行
if(istr.getline(tmp,256,delimiter))
{
   //删除旧串并申请一个新串
   delete []str;
   size=strlen(tmp)+1;
   try
   {
    str=new char[size];
   }
   catch(exception e)
   {
    Error(outOfMemory);
   }
   //拷贝tmp,返回读入字符个数
   strcpy_s(str,size,tmp);
   return (int)size-1;
}
else
   return -1; //文件结束时返回-1
}

int CString::Length()const
{
return (int)size;
}
int CString::IsEmpty(void)const
{
return size==1;
}
void CString::Clear()
{
str[0]=NULL;
size=1;
}
CString::~CString()
{
delete []str;
size=0;
}

////////////////////////////////////////////////////////////////////////////

//以下是用来测试的文件,大家不一定要下载

//如果对上面代码有不理解的,则可以下载以下代码,参看一下如何应用

// String类的使用.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "MyString.h"
#include <iostream>


void main()
{
int index=0,count=0;
char c;
//创建类实体
CString s1("12345"),s2("abc"),s3,s4(s2);
char *p=new char[10];
p="DEFGH";
cout<<"---- 初使化 ----"<<endl;
cout<<"实体 s1.str : "<<s1<<endl;
cout<<"实体 s2.str : "<<s2<<endl;
cout<<"实体 s3.str : "<<s3<<endl;
cout<<"实体 s4.str : "<<s4<<endl;
cout<<"字符串 p : "<<p<<endl<<endl;

//String=String
cout<<"---- = 重载 ----"<<endl;
s3=s1;
cout<<"s3 = s1 => s3.str : "<<s3<<endl;
s3=p;
cout<<"s3 = *p => s3.str : "<<s3<<endl<<endl;

//String==String、String!=String
//String>=String、String<=String
s3="";
cout<<"---- ==、!=、>=、<= 重载 ----"<<endl;
cout<<" s1 == s2 => Bool = "<<(s1==s2)<<endl;
cout<<" s1 != s2 => Bool = "<<(s1!=s2)<<endl;
cout<<" s1 <= s2 => Bool = "<<(s1<=s2)<<endl;
cout<<" s1 >= s2 => Bool = "<<(s1>=s2)<<endl<<endl;

//String+String
cout<<"---- + 重载 ----"<<endl;
s3=s1+s2;
cout<<"s3 = s1 + s2 => s3.str : "<<s3
   <<" 长度 s3 : "<<s3.Length()<<endl;
s3=p+s1;
cout<<"s3 = *p + s1 => s3.str : "<<s3
   <<" 长度 s3 : "<<s3.Length()<<endl<<endl;

//String+=String
s3="";
cout<<"---- += 重载 ----"<<endl;
s3+=s1;
cout<<"s3 += s1 => s3.str : "<<s3
   <<" 长度 s3 : "<<s3.Length()<<endl;
s3+=p;
cout<<"s3 += *p => s3.str : "<<s3
   <<" 长度 s3 : "<<s3.Length()<<endl<<endl;

//String[]
cout<<"---- [] 重载 ----"<<endl;
index=2;
cout<<"s1["<<index<<"]="<<s1[index]<<endl<<endl;


//Find(char c,int start)
s3="abcdef";
c='c';
index=2;
cout<<"---- 函数 Find(char c,int start) ----"<<endl;
cout<<"字符 '"<<c<<"' 在字符串 '"<<s3
   <<"' 中第一次出现的位置 :"<<s3.Find(c,index)<<endl<<endl;

//FindLast(char c)
s3="abcdefg";
c='d';
cout<<"---- 函数 FindLast(char c) ----"<<endl;
cout<<"字符 '"<<c<<"' 最后出现在字符串 '"<<s3<<"' "
   <<"的位置 : "<<s3.FindLast(c)<<" "<<endl<<endl;

//Substr(int index, int count)
s3="Using this function";
index=6,count=4;
cout<<"---- 函数 Substr(int index, int count) ----"<<endl;
cout<<"获取字符串 '"<<s3<<"' 中,从位置 "
   <<index<<" 开始的 "<<count<<" 个字符 : ";
s1=s3.Substr(index,count);
cout<<s1<<endl<<endl;

//Insert(const CString &s,int index)
s3="1234890";
index=3;
s1="567";
cout<<"---- 函数 Insert(const CString &s,int index) ----"<<endl;
cout<<"将字符串 '"<<s1<<"' 插入到从字符串 '"
   <<s3<<"' 第 "<<index<<" 个位置后面 : ";
s3.Insert(s1,index);
cout<<s3<<endl<<endl;

//Remove(int index,int count)
s3="1234564567890";
index=3;
count=3;
cout<<"---- 函数 Remove(int index,int count) ----"<<endl;
cout<<"从字符串的第 "<<index<<" 位开始的 "<<index<<" 个字符从 '"
   <<s3<<"' 中删除掉 : ";
s3.Remove(index,count);
cout<<s3<<endl<<endl;

//>>String,<<String
cout<<"---- <<、>> 重载 ----"<<endl;
cout<<"请输入字符串 : ";
cin>>s1;
cout<<"所输入的字符串为 : "<<s1
<<" 字符串长度为 : "<<s1.Length()<<endl<<endl;
  
}

//如果以上代码有错的,请大家帮我指证,谢谢
原文地址:https://www.cnblogs.com/xiangshancuizhu/p/2119170.html