c++string函数实现 已经加入注释解释 求赞

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<assert.h>
namespace yuren {

	class string

		// 管理字符串的数组,可以增删查改
		// 字符串数组的结尾有\0
		// 支持增删查改

	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;   //为后续遍历string时使用。
		iterator begin()
		{
			return _str;
		}
		const_iterator begin()const

		{
			return _str;
		}


		iterator end()
		{
			return _str + _size;
		}


		const_iterator end() const
		{
			return _str + _size;
		}

		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);

		}

		string(const char* str = "")  //构造函数

		{
			_size = strlen(str);
			_capacity = _size;
			_str = new char[_capacity + 1];//给'\0'留出位置
			strcpy(_str, str);

		}

		string(const string& s)  //拷贝构造
			:_capacity(0)
			, _size(0)
			, _str(nullptr)
		{

			string tmp(s._str);
			swap(tmp);
		}
		string& operator=(string s)  //赋值构造
		{
			swap(s);
			return *this;
		}



		~string()  //析构函数
		{
			delete[]_str;
			_size = _capacity = 0;
		}
		// 遍历  []需要写两个 读跟写
		// at 作用和operator[]类似,越界抛异常
		//读
		const char& operator[](size_t n)const
		{
			return _str[n];
		}
		//可读可写
		char& operator[](size_t n)
		{
			return _str[n];
		}
		//写字符 写字符串
		void pushback(const char& val) //加入单个字符
		{
			//第一步检查空间是否足够
			if (_size == _capacity)
			{
				//先开辟空间
				int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
				char* tmp = new char[newcapacity + 1];
				if (tmp == nullptr)
				{
					std::cout << "开辟失败" << std::endl;
					exit(-1);

				}
				strcpy(tmp, _str);
				delete[]_str;
				_str = tmp;
				_capacity = newcapacity;
			}
			_str[_size] = val;
			_str[_size + 1] = '\0';
			_size += 1;
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];//开辟n+1个大小的空间 加1的目的是为了后序遍历遇到'\0';
				if (tmp == nullptr)
				{
					std::cout << "开辟失败" << std::endl;
					exit(-1);
				}
				strncpy(tmp, _str, _size + 1);
				delete[]_str;
				_str = tmp;
				_capacity = n;
			}

		}
		size_t size()
		{
			return _size;
		}
		size_t capacity()
		{
			return _capacity;
		}
		void append(const char* val) //这里就是pushback一个字符串 
		{
			//第一步计算要oushback字符串的长度
			size_t n = strlen(val);
			//查看现有空间是否足够 如果不够开辟
			if (_size + n > _capacity)
			{
				//这里的开辟我们可以直接写成一个函数方便后续的调用 reserve
				reserve(_size + n);
			}
			//while 循环插入
			size_t v = size();
			while (*val != '\0')
			{
				_str[v] = *val;
				val++;
			}
			_str[_size + n] = '\0';
		}

		//运算符重载+=
		string& operator+=(const char& val)  //分两个一个是加字符 另一个是加一段字符串
		{
			if (_size + 1 > _capacity)
			{
				reserve(_size + 1);
			}
			_str[_size] = val;
			_str[_size + 1] = '\0';
			return *this;
		}
		string& operator+=(const char* ch)
		{

			append(ch);
			return *this;
		}

		string& insert(size_t pos, char chh)  //在某个位置处插入一个字符
		{
			assert(pos <= size());

			//检查空间
			if (_size + 1 > _capacity)
			{
				reserve(_size + 1);
			}
			//移动数据 
			char* ch = _str + pos;
			char* end = _str + _size;
			while (end >= ch)
			{
				*(end + 1) = *end;
				end--;
			}
			_str[pos] = chh;
			_size++;
			return *this;
		}
		string& insert(size_t pos, const char* chh)
		{
			//插入一段字符串 

				//先计算要插入的长度大小
			size_t len = strlen(chh);
			//检查空间是否足够 如果不够就要开空间
			if (len + _size > _capacity)
			{
				reserve(len + _size);
			}
			//开辟完成后插入数据
			char* begin = _str + pos;
			char* end = _str + _size;
			while (end >= begin)
			{
				*(end + len) = *end;
				end--;
			}
			//pos处的空间空出来了 接着插入这段字符串
			strncpy(_str, chh, len);
			_size += len;
			return *this;

		}

		string& erase(size_t pos, size_t len = npos)  //删除某一位置上长度为len的数据
		{
			assert(pos < _size);
			size_t leftLen = _size - pos;
			// 1、剩余的字符长度小于要删的长度  (后面全部删完)
			// 2、剩余的字符长度大于要删的长度  判断是否要移动数据
			if (len >= leftLen)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
			return*this;
		}

		size_t find(char ch, size_t pos = 0)
		{
			//从某一位置处查找字符ch
			assert(pos < _size);
			//遍历_str;找到该字符 然后是其他字符前移动就可
			char* begin = _str + pos;
			char* end = _str + _size;
			while (begin < end)
			{
				if (*begin == ch)
				{
					return begin - _str;
				}

				begin++;
			}
			return npos;
		}
		size_t find(char* ch, size_t pos = 0)
		{
			//从pos处开始 找一段字符串
			assert(pos < _size);
			char* ret = strstr(_str + pos, ch);
			if (ret)
			{
				return ret - _str;

			}
			else

			{
				return npos;
			}
		}
		void clear()
		{
			_size = 0;
			_str[0] = '\0';
		}
		const char* c_str() const
		{
			return _str;
		}

	private:
		size_t _size;
		size_t _capacity;
		char* _str;
		static const size_t npos;
	};
	const size_t string::npos = -1;



	inline bool operator<(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) < 0;
	}



	inline bool operator==(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) == 0;
	}


	inline bool operator<=(const string& s1, const string& s2)
	{
		return s1 < s2 || s1 == s2;
	}


	inline bool operator>(const string& s1, const string& s2)
	{
		return !(s1 <= s2);
	}


	inline bool operator>=(const string& s1, const string& s2)
	{
		return !(s1 < s2);
	}


	inline bool operator!=(const string& s1, const string& s2)
	{
		return !(s1 == s2);
	}


	std::ostream& operator<<(std::ostream& cout, const string& s)
	{
		for (auto ch : s)
		{
			cout << ch;
		}

		return cout;
	}


	std::istream& operator>>(std::istream& in, string& s)
	{
		s.clear();

		char ch;
		ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			ch = in.get();
		}

		return in;
	}

	
}
	#include"string.h"


using namespace yuren;

int main()

{
	string s1("hello");
	string s2("world");
	string s3 = s2;
	s1 += "world";
	std::cout << s1;
	s1 +='w';

	s1.pushback('c');
	s1.append("ao");
	s1.erase(0, 1);
	s1.find('c');
	s1.insert(2,"aoo");
	s1.erase(2, 3);




	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值