【C++】—— string模拟实现(三)

简介: 【C++】—— string模拟实现

【C++】—— string模拟实现(二)https://developer.aliyun.com/article/1621433

HL :: string 源码

 

#pragma once
#include<iostream>
#include<cassert>
 
template <typename T>
void Swap(T& x, T& y)
{
  T tmp = x;
  x = y;
  y = tmp;
}
namespace HL
{
  class string
  {
    friend std::ostream& operator<<(std::ostream& out, const HL::string& str);
    friend std::istream& operator>>(std::istream& in, HL::string& str);
  public:
    //构造函数
    /*string()
    {
      _str = new char[1];
      _str[0] = '\0';
      _size = 0;
      _capacity = 0;
    }
    
    string(char ch)
    {
      _str = new char[1];
      _str[0] = ch;
      _size = 0;
      _capacity = 0;
    }*/
    string(char ch = '\0')
    {
      _str = new char[2];
      _str[0] = ch;
      _str[1] = '\0';
      _size = 1;
      _capacity = 1;
    }
    string(const char* s)
    {
      size_t len = strlen(s);
      _str = new char[len + 1];
      memcpy(_str, s, len + 1);
      _size = len;
      _capacity = len;
    }
    string(const char* s, size_t n)
    {
      size_t len = strlen(s);
      if (n > len)
      {
        n = len;
      }
      _str = new char[n + 1];
      memcpy(_str, s, n);
      _str[n] = '\0';
      _size = n;
      _capacity = n;
    }
    string(const string& str)
    {
      _str = new char[str._capacity + 1];
      memcpy(_str, str._str, str._size + 1);
      _size = str._size;
      _capacity = str._capacity;
    }
    string(size_t n, char c)
    {
      _str = new char[n + 1];
      for (size_t i = 0; i < n; i++)
      {
        _str[i] = c;
      }
      _str[n] = '\0';
      _size = n;
      _capacity = n;
    }
 
    ~string()
    {
      delete[] _str;
      _str = nullptr;
      _size = _capacity = 0;
    }
 
    /*string& operator=(const string& str)
    {
      delete[] _str;
      _str = new char[str._capacity];
      memcpy(_str, str._str, str._size + 1);
      _size = str._size;
      _capacity = str._capacity;
      return *this;
    }*/
    /*string& operator= (const string& str)
    {
      string tmp(str);
      Swap(_str, tmp._str);
      Swap(_size, tmp._size);
      Swap(_capacity, tmp._capacity);
      return *this;
    }*/
    string& operator= (const string& str)
    {
      string tmp(str);
      swap(tmp);
      return *this;
    }
    /*string& operator= (const char* s)
    {
      size_t len = strlen(s);
      delete[] _str;
      _str = new char[len + 1];
      memcpy(_str, s, len + 1);
      _size = _capacity = len;
      return *this;
    }*/
    string& operator= (const char* s)
    {
      string tmp(s);
      Swap(_str, tmp._str);
      Swap(_size, tmp._size);
      Swap(_capacity, tmp._capacity);
      return *this;
    }
    string& operator= (char c)
    {
      delete[] _str;
      _str = new char[2];
      _str[0] = c;
      _str[1] = '\0';
      _size = _capacity = 1;
      return *this;
    }
    //string& operator= (char c)
    //{
    //  string tmp(c);
    //  Swap(_str, tmp._str);
    //  Swap(_size, tmp._size);
    //  Swap(_capacity, tmp._capacity);
    //  return *this;
    //}
 
    //迭代器
    typedef char* iterator;
    typedef const char* const_iterator;
    iterator begin()
    {
      return _str;
    }
    iterator end()
    {
      return (_str + _size);
    }
    const_iterator begin() const
    {
      return _str;
    }
    const_iterator end() const
    {
      return (_str + _size);
    }
 
    //下标访问 [ ]
    char& operator[] (size_t pos)
    {
      assert(pos >= 0 && pos < _size);
      return *(_str + pos);
    }
    const char& operator[] (size_t pos) const
    {
      assert(pos >= 0 && pos < _size);
      return *(_str + _size);
    }
 
    //扩容
    void reserve(size_t n)
    {
      if (n > _capacity)
      {
        char* s = new char[n + 1];
        memcpy(s, _str, _size);
        delete[] _str;
        _str = s;
        _capacity = n;
      }
    }
 
    //增
    void push_back(char c)
    {
      if (_size >= _capacity)
      {
        reserve((_capacity == 0) ? 4 : 2 * _capacity);
      }
      _str[_size] = c;
      _size++;
      _str[_size] = '\0';
    }
    void append(const string& str)
    {
      size_t n = _size + str._size;
      if (n > _capacity)
      {
        reserve(n);
      }
      for (int i = 0; i < str._size; i++)
      {
        _str[_size + i] = str._str[i];
      }
      _size += str._size;
      _str[_size] = '\0';
    }
    void append(const char* s)
    {
      size_t len = strlen(s);
      size_t n = _size + len;
      if (n > _capacity)
      {
        reserve(n);
      }
      for (int i = 0; i < len; i++)
      {
        _str[_size + i] = s[i];
      }
      _size = n;
      _str[_size] = '\0';
    }
    void append(size_t n, char c)
    {
      if (_size + n > _capacity)
      {
        reserve(_size + n);
      }
      for (int i = 0; i < n; i++)
      {
        _str[_size + i] = c;
      }
      _size += n;
      _str[_size] = '\0';
    }
    string& operator+=(const string& str)
    {
      this->append(str);
      return *this;
    }
    string& operator+=(const char* s)
    {
      this->append(s);
      return *this;
    }
    string& operator+=(char c)
    {
      this->push_back(c);
      return *this;
    }
 
    //insert 、erase
    void insert(size_t pos, const string& str)
    {
      assert(pos >= 0 && pos < _size);
      size_t len = str._size;
      size_t n = _size + len;
      if (n > _capacity)
      {
        reserve(n);
      }
      //挪动数据
      for (size_t i = n; i >= pos + len; i--)
      {
        _str[i] = _str[i - len];
      }
      memcpy(_str + pos, str._str, str._size);
      _size += str._size;
      _str[_size] = '\0';
    }
    void insert(size_t pos, const char* s)
    {
      assert(pos >= 0 && pos < _size);
      size_t len = strlen(s);
      size_t n = _size + len;
      if (n > _capacity)
      {
        reserve(n);
      }
      //挪动数据
      for (size_t i = n; i >= pos + len; i--)
      {
        _str[i] = _str[i - len];
      }
      memcpy(_str + pos, s, len);
      _size += len;
      _str[_size] = '\0';
    }
    void insert(size_t pos, size_t n, char c)
    {
      assert(pos >= 0 && pos < _size);
      if (_size + n > _capacity)
      {
        reserve(_size + n);
      }
      //挪动数据
      for (size_t i = _size+n; i >= pos + n; i--)
      {
        _str[i] = _str[i - n];
      }
      for (size_t i = 0; i < n; i++)
      {
        _str[pos + i] = c;
      }
      _size += n;
      _str[_size] = '\0';
    }
    void erase(size_t pos, size_t len = npos)
    {
      assert(pos >= 0 && pos < _size);
      if (len == npos)
      {
        _str[0] = '\0';
        _size = 0;
        return;
      }
      for (size_t i = pos; (len + i) < _size; i++)
      {
        _str[i] = _str[i + len];
      }
      _size -= len;
      _str[_size] = '\0';
    }
 
    //find
    size_t find(const string& str, size_t pos = 0)
    {
      assert(pos >= 0 && pos < _size);
      char* tmp = strstr(_str + pos, str._str);
      if (tmp == nullptr)
      {
        return -1;
      }
      return tmp - _str;
    }
    size_t find(const char* s, size_t pos = 0)
    {
      assert(pos >= 0 && pos < _size);
      char* tmp = strstr(_str + pos, s);
      if (tmp == nullptr)
      {
        return -1;
      }
      return tmp - _str;
    }
    size_t find(char c, size_t pos = 0)
    {
      assert(pos >= 0 && pos < _size);
      for (size_t i = pos; i < _size; i++)
      {
        if (_str[i] == c)
        {
          return i;
        }
      }
      return -1;
    }
    
    //swap
    void swap(string& str)
    {
      Swap(_str, str._str);
      Swap(_size, str._size);
      Swap(_capacity, str._capacity);
    }
 
    //c_str
    const char* c_str() const
    {
      return _str;
    } 
    char* c_str()
    {
      return _str;
    }
    
    //substr
    string substr(size_t pos = 0, size_t len = npos) const
    {
      assert(pos >= 0 && pos < _size);
      size_t n = 0;
      if (len == npos || pos + len > _size)
      {
        n = _size - pos;
      }
      else
      {
        n = len;
      }
      string ret;
      for (size_t i = 0; i < n; i++)
      {
        ret += _str[pos + i];
      }
      return ret;
    }
 
    //其他成员函数
    size_t size() const
    {
      return _size;
    }
    size_t length()const
    {
      return _size;
    }
    size_t capacity()const
    {
      return _capacity;
    }
    void clear()
    {
      _str[0] = '\0';
      _size = 0;
    }
    bool empty()const
    {
      return _size == 0;
    }
    void resize(size_t n)
    {
      if (n > _capacity)
      {
        reserve(n);
      }
      _size = n;
      _str[_size] = '\0';
    }
    void resize(size_t n, char c)
    {
      if (n > _capacity)
      {
        reserve(n);
      }
      for (size_t i = _size; i < n; i++)
      {
        _str[i] = c;
      }
      _size = n;
      _str[_size] = '\0';
    }
  private:
    char* _str;
    size_t _size;
    size_t _capacity;
    const static size_t npos;
  };
 
  const size_t HL::string::npos = -1;
 
  std::ostream& operator<<(std::ostream& out, const HL::string& str)
  {
    //for (int i = 0; i < str.size(); i++)
    //{
    //  out << str[i];
    //}
    //return out;
    for (auto ch : str)
    {
      out << ch;
    }
    return out;
  }
  std::istream& operator>>(std::istream& in, HL::string& str)
  {
    char s[128] = { 0 };
    char ch;
    ch = in.get();
    while (ch == ' ' || ch == '\n')
    {
      ch = in.get();
    }
    str.clear();
    int i = 0;
    while (ch != '\n')
    {
      s[i] = ch;
      i++;
      if (i == 127)
      {
        s[i] = '\0';
        str += s;
        i = 0;
      }
      ch = in.get();
    }
    if (i)
    {
      str += s;
    }
    return in;
  }
};
相关文章
|
24天前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
49 5
|
24天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
38 2
|
2月前
|
C++ 容器
|
2月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
26 1
|
2月前
|
C++ 容器
|
2月前
|
C++ 容器
|
2月前
|
存储 C++ 容器
|
2月前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
45 4
|
2月前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
74 2
|
2月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(三)
【C++】C++ STL 探索:String的使用与理解