C++初阶(十二)string的模拟实现

简介: C++初阶(十二)string的模拟实现

一、string类的模拟实现


1、构造、拷贝构造、赋值运算符重载以及析构函数

3557994367274a239433caba4cb18f13.png

2、迭代器类

ec46c80e2512419faca102489ba9cf93.png

3、增删查改类

638c0cea008d41958249580886b7ccc0.png

c0416d8c3bd844ba8bb2c6e79eeadb79.png

7f22477342d743b38a3d60b92058a12c.png

6e8426d684084aaa95e248cee943e4b3.png

a6d0afc73c394511928b3a5d201ef073.png

4、io类

408f2bf1a9b6452c990ed949865555cf.png

5、扩容类

47215f440602424f96b3ebb0f687e5c8.png

6、完整代码

namespace bit
{
  class string
  {
  public:
    typedef char* iterator;
    typedef const char* const_iterator;
    const_iterator beagin() const
    {
      return _str;
    }
    const_iterator end() const
    {
      return _str + _size;;
    }
    iterator begin()
    {
      return _str;
    }
    iterator end()
    {
      return _str + _size;
    }
    void insert(size_t pos, char ch)
    {
      assert(pos <= _size);
      if (_size == _capacity)
      {
        reserve(_capacity == 0 ? 4 : _capacity *= 2);
      }
      size_t end = _size + 1;
      while (end >pos)
      {
        _str[end] = _str[end-1];
        end--;
      }
      _str[pos] = ch;
      _size++;
    }
    void insert(size_t pos, const char* ch)
    {
      assert(pos <= _size);
      size_t len = strlen(ch);
      if (_size + len > _capacity)
      {
        reserve(_size + len);
      }
      size_t  end = _size;
      while (end > pos)
      {
        _str[end + len] = _str[end];
        --end;
      }
      strncpy(_str + pos, ch, len);
      _size += len;                                                                                                               
    }
    void erase(size_t pos, size_t len = npos)
    {
      assert(pos < _size);
      if (len == npos || pos + len > _size)
      {
        _str[pos] = '\0';
        _size = pos;
      }
      else
      {
        size_t begin = _size + len;
        while (begin <= _size)
        {
          _str[pos++] = _str[begin++];
        }
        _size -= len;
      }
    }
    void push_back(char ch)
    {
      if (_size == _capacity)
      {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
      }
      _str[_size] = ch;
      ++_size;
      _str[_size] = '\0';
    }
    void append(const char* str)
    {
      size_t len = strlen(str);
      if (_size + len > _capacity)
      {
        reserve(_size + len);
        strcpy(_str + _size, str);
        _size += len;
      }
    }
    string& operator+=(char ch)
    {
      push_back(ch);
      return *this;
    }
    string& operator+=(const char* ch)
    {
      append(ch);
      return *this;
    }
    string(const char* str = "")
      :_size(strlen(str))
      ,_capacity(_size)
    {
      _str = new char[_size + 1];
      strcpy(_str, str);
    }
    ~string()
    {
      delete[] _str;
      _str = nullptr;
      _size = 0;
      _capacity = 0;
    }
    string(const string& s)
      :_str(nullptr)
      , _size(0)
      , _capacity(0)
    {
      string tmp(s._str);
      swap(tmp);
    }
    string& operator=(string s)
    {
      swap(s);
      return *this;
    }
    void reserve(size_t n)
    {
      if (n > _capacity)
      {
        char* tmp = new char[n + 1];
        strcpy(tmp, _str);
        _str = tmp;
        _capacity = n;
      }
    }
    void resize(size_t n,char ch='\0')
    {
      if (n <= _size)
      {
        _str[n] = ch;
        _size = n;
      }
      else
      {
        reserve(n);
        while (_size < n)
        {
          _str[_size++] = ch;
        }
        _str[_size] = '\0';
      }
    }
    void clear()
    {
      _str[0] = '\0';
      _size = 0;
    }
    void swap(string& s)
    {
      std::swap(_str, s._str);
      std::swap(_size, s._size);
      std::swap(_capacity, s._capacity);
    }
    size_t find(char ch, size_t pos = 0)
    {
      for (size_t i = pos; i < _size; i++)
      {
        if (_str[i] == ch)
        {
          return i;
        }
      }
      return npos;
    }
    size_t find(const char* sub, size_t pos=0)
    {
      const char* p = strstr(_str + pos, sub);
      if (p)
      {
        return p - _str;
      }
      else
      {
        return npos;
      }
    }
    string substr(size_t pos, size_t len = npos)
    {
      string s;
      size_t end = pos + len;
      if (len == npos || pos + len >= _size)
      {
        len = _size - pos;
        end = _size;
      }
      s.reserve(len);
      for (size_t i = pos; i <= end; i++)
      {
        s += _str[i];
      }
      return s;
    }
  private:
    char* _str;
    size_t _size;
    size_t _capacity;
    const static size_t npos;
  };
  const size_t string::npos = -1;
  ostream& operator<< (ostream& out, string& s)
  {
    for (auto ch : s)
    {
      out << ch;
    }
    return out;
  }
  istream& operator>> (istream& in, string& s)
  {
    s.clear();
    char buff[129];
    size_t i = 0;
    char ch;
    ch = in.get();
    while (ch != ' ' && ch != '\0')
    {
      buff[i++] = ch;
      if (i == 128)
      {
        buff[i] = '\0';
        s += buff;
        i = 0;
      }
      s += ch;
      ch = in.get();
    }
    if (i != 0)
    {
      buff[i] = '\0';
      s += buff;
    }
    return in;
  }
}


目录
相关文章
|
15天前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
38 5
|
15天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
26 2
|
2月前
|
C++ 容器
|
2月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
23 1
|
2月前
|
C++ 容器
|
2月前
|
C++ 容器
|
2月前
|
存储 C++ 容器
|
2月前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
38 4
|
2月前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
72 2
|
2月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(三)
【C++】C++ STL 探索:String的使用与理解