///////////////////////////////////////
//
// 文件名: 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;
}
//如果以上代码有错的,请大家帮我指证,谢谢