C++ string容器模拟实现(初阶,不含分配器)

#pragma once
#include<iostream>
#include<assert.h>
using std::cout;
using std::endl;
using std::cin;
using std::ostream;
using std::exception;
using std::istream;
namespace sxh
{
	class string
	{
	public:

		typedef char* iterator;
		static const size_t nops = -1;

		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str+_size;
		}

		string(const char* str = "") :_str(new char[strlen(str)+1]), _size(strlen(str)), _capacity(_size)
		{
			strcpy(_str, str);
		}

		/*string(const string& str):_str(new 
         char[str._capacity]),
        _size(str._size),
        _capacity(str._capacity)
		{
			strcpy(this->_str, str._str);
		}*/

		string(const string& str)
		{
            //我在vs2022中模拟list测试list<string> 时,不知道为什么在list构造函数初始化列表中 
            //使用data(sting())时会崩溃.调试后发现data里的数据和正常调用时的数据不同,data不是 
            //全零,且_size和_capacity显 
            //示最大值,_str的地址显示非零的随机地址
			//之后拷贝构造结束后释放temp时,会直接程序崩溃
			//故我在开始时将_str设为空
			this->_str = nullptr;
			string temp(str._str);
			this->swap(temp);
		}

		~string()
		{
			delete[] this->_str;
			_str = nullptr;
			_size = 0;
			_capacity = 0;
		}

        //string function
		void swap(string& s1)
		{
			std::swap(this->_str, s1._str);
			std::swap(this->_size, s1._size);
			std::swap(this->_capacity, s1._capacity);
			
		}
		void reserve(unsigned int capacity)
		{
			char* temp = new char[capacity + 1];
			if (this->_str != nullptr)
			{
               strcpy(temp, this->_str);
			   delete[] this->_str;
			   this->_str = temp;
			}
			else
			{
				temp = nullptr;
				_str = temp;
			}
			
			_capacity = capacity;
		}

		void push_back(const char ch)
		{
			if (_size == _capacity)
			{
				_capacity = _capacity == 0 ? 2 : _capacity * 2;
				reserve(_capacity);
			}
			_str[_size] = ch;
			_str[_size + 1] = '\0';
			++_size;
		}

		void append(const char* str)
		{
			if (this->_size + strlen(str) > this->_capacity)
			{
				_capacity = _size + strlen(str);
				reserve(_capacity);
			}
			strcpy(_str + _size, str);
			_size += strlen(str);
			_str[_size] = '\0';
		}

		size_t size()const
		{
			return _size;
		}
        size_t size()const
        {
            return _capacity; 
        }
        
		string& insert(size_t pos,const string& str)
		{
			assert(pos <= _size);
			if (this->_capacity < this->_size + str._size)
			{
				_capacity = _capacity * 2 + str._size;
				reserve(_capacity);
			}

			int length = this->_size;
			while (length >=(int)pos)
			{
				this->_str[length + str._size] = this->_str[length];
				length--;
			}
			for (size_t i = 0; i < str._size; ++i)
			{
				this->_str[pos] = str[i];
				pos++;
			}
			this->_size += str._size;

			return *this;

		}
		void insert(size_t pos, size_t count,const char ch)
		{
			assert(pos <= _size);
			if (this->_capacity <= this->_size+count)
			{
				reserve(_size+count);
			}
			int length = this->_size;
			while (length >= (int)pos)
			{
				this->_str[length + count] = this->_str[length];
				length--;
			}
			for (size_t i = 0; i < count; ++i)
			{
				this->_str[pos] = ch;
				pos++;
			}
			this->_size += count;

			if (this->_str[_size] != '\0')
				this->_str[_size] = '\0';
		}
		string& insert(size_t pos, const char* str)
		{
			assert(pos <= _size);
			size_t len = strlen(str);
			if (this->_capacity < this->_size + len)
			{
				_capacity = _capacity * 2 + len;
				reserve(_capacity);
			}
			int length = this->_size;
			while (length >= (int)pos)
			{
				this->_str[length + len] = this->_str[length];
				length--;
			}

			for (size_t i = 0; i < len; ++i)
			{
				this->_str[pos] = str[i];
				pos++;
			}
			    this->_size += len;

			if (this->_str[_size] != '\0')
				this->_str[_size] = '\0';


			return *this;

		}
		//resize(19)
		//"helloworld"
		void resize(size_t newsize,char ch = '\0')
		{
			if (newsize > this->_capacity)
			{
				reserve(_capacity+newsize);
			}
			//resize(2)
			if (newsize < _size)
			{
				_str[newsize] = '\0';
				_size = newsize;
			}
			else
			{
				for (size_t i = _size; i < newsize; ++i)
				{
					_str[i] = ch;
				}
				_size = newsize;
				_str[_size] = '\0';
			}

		}

		void erase(size_t pos,  size_t len = nops)
		{
			assert(pos < _size);
			if (len >= _size - pos)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				for (size_t i = pos + len; i < _size; ++i)
				{
					_str[pos] = _str[i];
					++pos;
				}
				_size -= len;
			}
		}

		size_t find(const char ch,const size_t pos = 0)
		{
			for (size_t i = pos; i < _size; i++)
			{
				if (_str[i] == ch)
				{
					return i;
				}
			}
			
			return nops;
		}

		size_t find(const char* ch, const size_t pos = 0)
		{
			for (size_t i = pos; i < _size; ++i)
			{
				if (_str[i] == *ch)
				{
					ch++;
					if (*ch == '\0')
					{
						return i;
					}
				}
			}

			return nops;
		}

		//string operator function 
		/*string& operator=(const string& str)
		{
			this->_str = new char[str._capacity];
			this->_size = str._size;
			this->_capacity = str._capacity;
			strcpy(this->_str, str._str);
			return *this;
		}*/

		string& operator=(string& str)
		{
			this->swap(str);
			return *this;
		}
      
        string& operator=(const char* str)
		{
			this->append(str);
			return *this;
		}

		char operator[](size_t i)const
		{
			return _str[i];
		}

		char operator[](const int i)const
		{
			return _str[i];
		}

		string& operator+=(const char* str)
		{
			this->append(str);
			return *this;
		}

		string& operator+=(const char str)
		{
			this->push_back(str);
			return *this;
		}

		void getline(istream& in)
		{
			while (1)
			{
				char ch;
				ch = in.get();
				if (ch == '\n')
				{
					break;
				}
				*this += ch;
			}
		}

		friend ostream& operator<<(ostream& os, const string& str);
		friend istream& operator>>(istream& is, string& str);

	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};

	ostream& operator<<(ostream& os, const string& str)
	{
		for (size_t i = 0; i < str.size(); ++i)
		{
			os << str[i];
		}
		return os;
	}

	istream& operator>>(istream& in,string& str)
	{
		while (1)
		{
			char ch;
			ch = in.get();
			if (ch == '\n'|| ch == '\0')
			{
				break;
			}
			str += ch;
		}
		return in;
	}



}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值