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