zoukankan      html  css  js  c++  java
  • 别人的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;
      
    }
    
    //如果以上代码有错的,请大家帮我指证,谢谢
    
  • 相关阅读:
    python3 操作excel(读操作)
    display:inline-block;产生间隙解决方法
    vedio自定义样式
    angularjs路由
    移动端设置字体px转换rem的脚本
    div在不固定高度的情况下垂直或者水平居中
    css气泡地址和分享地址
    js点击按钮div显示,点击div或者body和按钮,div隐藏
    js倒计时跳转页面
    点击按钮div显示,点击div或者document,div隐藏
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/2119170.html
Copyright © 2011-2022 走看看