string类功能实现

#pragma once 
#include<iostream>
using namespace std;
#include<assert.h>
namespace xxoo
{

	class string
	{
	public:
		typedef char* iterator;
	public:
		//构造函数
		string(const char* str = "")
		{
			if (str == nullptr)
			{
				assert(false);
				return;
			}
			
			//开辟空间
			_size = strlen(str);
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		//拷贝构造函数
		string(const string& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			string tmp(s);
			swap(_str, tmp._str);
		}
		
		//赋值=重载
		string& operator=(const string& s)
		{
			//避免自赋值   d1=d1
			if (this != &s)
			{
				string tmp(s);
				swap(_str, tmp._str);
			}
			return *this;
		}

		//析构函数
		~string()
		{
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
		}

		//迭代器
		//iterator 是char*
		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}
		
		//modify
		//插入数据
		void push_back(char c)//插入一个字符
		{
			//先判断需不需要扩容
			if (_size == _capacity)
			{
				//扩容
				reserve(_capacity * 2);
				_str[_size++] = c;
				_str[_size] = '\0';
			}
		}

		//清除数据
		void clear()
		{
			_size = 0;
			_str[_size] = '\0';
		}

		//将sring转成c_str()
		const char* C_Str()const
		{
			return _str;
		}
		

		//扩容
		void reserve(size_t newCapacity)
		{
			//判断这个newCapacity是否比旧capacity大
			if (newCapacity > _capacity)
			{
				//扩容
				char* tmp = new char[newCapacity + 1];
				strcpy(tmp, _str);//将原来的数据拷贝到新空间下面
				delete[] _str;//删除旧空间
				
				_str = tmp;
				_capacity = newCapacity;
				
			}
		}

		//关于容量的操作
		size_t size()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}

		//判断时候为空
		bool empty()const
		{
			return _size == 0;
		}

		//resize
		void resize(size_t newSize, char c = '\0')
		{
		//1.先判断newSize是否比_size大
			//2.再判断newSize是否比_capacity大 看看是否需要扩容
			if (newSize > _size)
			{
				if (newSize > _capacity)
				{
					reserve(newSize);
					
				}
				//不大的话直接在_str+_size后面插入
				memset(_str + _size, c, newSize - _size);
			}
		}

		//重载[] 
		char& operator[](size_t index)
		{
			//判断下标是否合理
			assert(index < _size);
			return _str[index];
		}

		const char& operator[](size_t index)const
		{
			assert(index < _size);
			return _str[index];
		}


		//判断大小  借住strcmp
 		bool operator <(const string& s)const
		{
			int ret = strcmp(_str, s._str);
			if (ret < 0)
				return true;
			return false;
		}

		bool operator>=(const string& s)const
		{
			return !(*this < s);
		}
		
		bool operator>(const string& s)const
		{
			int ret = strcmp(_str, s._str);
			if (ret > 0)
				return true;
			return false;
		}

		bool operator<=(const string& s)const
		{
			return !(*this > s);
		}

		bool operator==(const string& s)const
		{
			int ret = strcmp(_str, s._str);
			if (ret == 0)
				return true;
			return false;
		}

		bool operator!=(const string& s)const
		{
			return !(*this == s);
		}


		//返回一个字符在字符串中的位置
		size_t find(char c, size_t pos = 0)//给pos,不然从0开始找
		{
			for (int i = 0; i < _size; i++)
			{
				if (_str[i] == c)
				{
					return i;
				}
			}
			return -1;//没找到
		}

		//返回一个字符串的位置 借用strsub匹配字符串函数
		size_t find(const char* str, size_t pos = 0)
		{
			assert(str);
			assert(pos < _size);
			
			//返回的是一个指针,所以用指针来接收
			const char* ptr = strstr(_str, str);
			if (ptr != NULL)
			{
				//要找到下标  用指针减去指针
				return ptr - _str;
			}
			return -1;
		}

		

		//插入数据  一个字符
		string& insert(size_t pos, char c)
		{
			assert(pos < _size);
			//判断是否需要扩容
			if (_size == _capacity)
			{
				reserve(_capacity * 2);
			}
			//移动数据 从后面一个一个挪
			for (int i = _size;i>=pos;--i)
			{
				_str[i + 1] = _str[i];
			}
			_str[pos] = c;
			_str[_size] = '\0';
			return *this;
		}

		//插入一个字符串
		string& insert(size_t pos, const char* str)
		{
			size_t len = strlen(str);
			//判断
			if (_size + len > _capacity)
			{
				//扩容
				reserve(_capacity * 2);
			}
			
			//挪动数据
			for (int i = _size; i >= (int)pos; --i)
			{
				_str[len + i] = _str[i];
			}

			//拷贝字符串
			while (*str != '\0')
			{
				_str[pos++] = *str++;
			}

			_size += len;
			return *this;
		}

		//删除pos位置上的元素,并返回该元素的下一个位置
		string& erase(size_t pos, size_t len)//删除多少个
		{
			//判断pos合理性
			assert(pos < _size);
			if (pos + len >= _size)//那么后面全是0
			{
				_str[pos] = '\0';//在pos的位置上设置0
				_size = pos;
			}
			else
			{
				//用strcpy拷贝函数  内存重叠
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
			return *this;
		}
		private:
			friend ostream& operator<<(ostream& _cout, const xxoo::string& s);
			friend istream& operator>>(istream& _cin,xxoo::string& s);
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}

//输入流重载
istream& xxoo::operator>>(istream& _cin, xxoo::string& s)
{
	char* str = new char[100];
	char* buf = str;
	int i = 1;
	//预处理:跳过流里面的所有空格和回车
	while ((*buf = getchar()) == ' ' || (*buf == '\n'));
	
	for (;; ++i)
	{
		if (*buf == '\n')
		{
			*buf = '\0';
			break;
		}
		else if (*buf = ' ')//空格跳出
		{
			*buf = '\0';
			break;
		}
		else if (i % 100 == 0)//空间不足
		{
			i += 100;
			str = (char*)realloc(str, i);
		}
		else//每次getchar()一个值
		{
			buf = (str + i);//为了避免realloc返回首地址改变,不适用++buf,而是用str加上偏移量

			//每次读取一个字符
			
			*buf = getchar();
		}
	}

	//输入完成,更新s
	s._str = str;
	s._capacity = s._size = i;
	
}

//输出流重载
ostream& xxoo::operator<<(ostream& _cout, const xxoo::string& s)
{
	for (size_t i = 0; i < s.size(); ++i)
	{
		_cout << s[i];
	}
	return _cout;
}

如有错误,多多指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值