模拟实现string类的增删查改

//string.h   头文件函数接口的声明以及变量的声明部分

#ifndef __String__
#define __String__
#include <iostream>
#include <assert.h>
using namespace std;
class  String
{
public:

    friend ostream & operator <<(ostream& os, const String& s);

    String(const char *s = "");

    String(const String &s );

    ~ String();

    size_t Capacity(const char *s);

    char& operator[] (size_t pos);

    const char& String::operator[](size_t pos)const;

    String& operator+= (const String& str);


    String& operator+= (const char* s);

    String& operator+= (char c);

    void Push_Back(char c);

    String& Erase(size_t pos , size_t len );

    String Substr(size_t pos , size_t len ) const;

    String& operator= (const String& s);

    String& Insert(size_t pos, const String& str, size_t Subpos, size_t Sublen);

    int  Find(const char *s ) const;

private:
    size_t _size;      //用来表示字符串的长度
    size_t _capacity; //用来表示所开辟的动态内存的大小
    char *_str;
}; 
#endif // __String__



//String.cpp 函数的实现部分

#include "String.h"
ostream & operator <<(ostream& os, const String& s)
{
     os << s._str;
     return os;
}

String::String(const char *s )
:_capacity(1)
,_str(new char[Capacity(s)])

{
    strcpy(_str, s);
    _size = strlen(_str);
}

String::String(const String &s)
{
    _str = new char[Capacity(s._str)+1];
    strcpy(_str, s._str);
    _size = strlen(_str);
    _capacity = s._capacity;
}

String::~String()
{
    if (_str != NULL)
    {
        delete[] _str;
        _str = NULL;
        _capacity = _size = 0;
        cout << "~String()" << endl;
    }

}

char& String::operator[](size_t pos)  //改
{
    assert(pos < _size);
    return _str[pos];

}

const char&  String::operator[](size_t pos)const
//在成员函数后加const,const修饰this指针所指向的对象,也就是保证调用这个
//const成员函数的对象在函数内不会被改变。
{
    assert(pos < _size);
    return _str[pos];

}

String& String::operator+= (const String& str)
{
    this->operator+=(str._str);
    return *this;
}

String& String::operator+= (const char* s)
{
    _str = (char*)realloc(_str, Capacity(s));
    strcpy(_str + _size, s);
    _size = strlen(_str);
    return *this;

}

String& String::operator+= (char c)
{
    char *tmp = &c;
    char *s = tmp;
    *(++tmp) ='\0';
    this->operator+=(s);
    return *this;
}

void String::Push_Back(char c)
{
    this->operator+=(c);
}

String&  String::Erase(size_t pos, size_t len)  
//从指定结点开始删除到指定长度
{
    assert(pos < _size);
    if ((pos == _size) || (len == 0))  
    //不删除元素或者删除'\0'或者其之后的元素
    {
        return *this;
    }
    else if ((_str + pos + len)<(_str + _size))  
    //_size+_str刚好指向'\0',删除的数据未超过字符串长度
    {
        //挪动数据
        while (*(_str+pos+len))
        {
            *(_str + pos) = *(_str + pos + len);
            pos++;
        }
        *(pos + _str) = *(_str + pos + len);
        _size = strlen(_str);
        return *this;
    }
    else
    {
        *(pos + _str) = *(_size + _str);
        _size = strlen(_str);
        return *this;
    }
}

String String::Substr(size_t pos, size_t len) const 
//从某个结点截取多长的字符串,是为了防止定义为const的String类的对象被修改
{
    assert(pos < _size);
    String tmp;
    char *cur = _str;
    while ((*(_str + pos) !='\0') && (len != 0)&&(*cur!='\0'))
    {
        tmp += *(_str + pos);
        pos++;
        len--;
        cur++;
    }
    return tmp;
}

String& String::operator= (const String& s)
{
    _str = new char[Capacity(s._str)];
    strcpy(_str, s._str);
    _size = strlen(_str);
    return *this;
}

String& String::Insert(size_t pos, const String& str, size_t Subpos, size_t Sublen)
//指定结点,插入指定String对象的指定位置开始的指定长度字符串
//注意使用指针访问数组元素和下标访问数组元素之间的联系和区别
//注意无符号数和有符号数之间的运算会发生隐式类型提升
{
    assert(pos < _size);
    String s=str.Substr(Subpos,Sublen);
    //开辟空间
    _str = (char*)realloc(_str,Capacity(s._str)*sizeof(char));
    size_t end = strlen(_str)+strlen(s._str);
    size_t count = Sublen;

    //挪动数据
    if (pos == _size )   //从'/0'位置处插入字符串
    {
        return *this += s;
    }
    else
    {

        //挪出Sublen个空间
        while (count)
        {
            if ((int)_size > (int)pos-1)
            {
                *(_str + end) = *(_str + _size);
            }
            _size--;
            end--;
            count--;
        }
        //插入数据
        count = s._size;
        char *cur = s._str;
        while (count)
        {
            *(_str + pos) = *(cur);
            cur++;
            pos++;
            count--;
        }
        return *this;
    }
}


int  String::Find(const char *s) const
{
    char *cur1 = _str;
    const char *cur2 = s;
    size_t pos = 0;
    while (cur1)
    {
        //abcde  cd

        while (*cur1 == *cur2)
        {
            cur1++;
            cur2++;
        }
        if (*cur2 == '\0')
        {
            return pos;
        }
        //ab   abde
        else  if (*cur1 == '\0'&&*cur2 != '\0')
        {
            return -1;
        }
        else
        {
            pos++;
            cur2 = s;
            cur1++;
        }
    }
    return  -1;

}

size_t String::Capacity(const char *s)
{
    _capacity += strlen(s) ;  //需要多大容量就增大多少容量
    return _capacity;
}



//test.cpp部分测试用例,想测试哪部分功能放开哪部分代码注释

#include "String.h"


int main()
{
//构造

    // String s("1234");
    //cout << s << endl;

//更改    
    //s[3] = '2';
    //cout << s << endl;
    //cout << s[3] << endl;
    //const String s1("1234");
    //cout << s1 << endl;

//实现+=操作符的重载
    //String s2("56");
    //s += s2;
    //cout << s << endl;
    //s += 'c';
    //cout << s << endl;

//尾插
    //s.Push_Back('s');
    //cout << s << endl;

//从指定结点开始删除到指定长度
    //String s4("123456");
    //cout << s4<< endl;
    //s4.Erase(5, 8);
    //cout << s4 << endl;

 //从某个结点截取多长的字符串
//  String s5(s4.Substr(1, 2));
 //  s5 = s1;
 //  cout << s5 << endl;

//指定结点,插入指定String对象的指定位置开始的指定长度字符串
    //String s1("abcde  ");
    //String s2("fghjk");
    //s1.Insert(6, s2, 3, 5);
    //cout << s1 << endl;
    //string s1("abcde ");
    //string s2("fghjk");
    //s1.insert(6, s2, 3, 5);//abcjkde 

//找指定字符串
    //String s1("abcdef");
    //cout<<s1.Find("hg")<<endl;
    //String s1("abcd");
    //s1[1] = 'a';
    //cout << s1 << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值