string模拟实现

该文章介绍了如何使用C++从头模拟实现一个简单的string类,包括构造函数、拷贝构造函数、赋值重载、迭代器、大小、容量、字符串比较、字符和字符串的追加、插入、删除、查找、交换等基本操作。此外,还提供了与输入输出流的重载操作符。
摘要由CSDN通过智能技术生成

string模拟实现

🌟🌟hello,各位读者大大们你们好呀🌟🌟
🚀🚀系列专栏:【C++的学习】
📝📝本篇内容:C++容器string模拟实现
⬆⬆⬆⬆上一篇:list模拟实现
💖💖作者简介:轩情吖,请多多指教(> •̀֊•́ ) ̖́-

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <iostream>
#include <stdio.h>
using namespace std;
namespace lnb
{
	class string
	{
	public:
		typedef char* iterator;//迭代器
		typedef const char* const_iterator;//const对象的迭代器
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin()const
		{
			return _str;
		}
		const_iterator end()const
		{
			return _str + _size;
		}


		string(const char* str = "")//构造函数,默认构造函数为空字符串
			:_size(strlen(str))
		{
			_capacity = _size;
			_str = new char[_capacity + 1];//有一个'\0',因此需要多开辟一个空间
			strcpy(_str, str);
		}

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

		string(const string& str)//拷贝构造函数
			:_size(str._size),
			_capacity(str._capacity)
		{
			_str = new char[str._capacity + 1];
			strcpy(_str, str._str);
		}

		string& operator=(const string& str)//赋值重载
		{
			if (this != &str)//防止自己给自己赋值,导致出现bug(随机值)
			{
				char* tmp = new char[str._capacity + 1];//tmp防止开辟空间失败导致_str不可用
				delete[] _str;
				_str = tmp;
				strcpy(_str, str._str);
				_capacity = str._capacity;
				_size = str._size;
			}
			return *this;
		}

		size_t size()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}

		char* c_str()const//以c语言方式的字符串返回
		{
			return _str;
		}


		//字符串比较,可以复用
		bool operator>(const string& str)const
		{
			return strcmp(_str, str._str) > 0;
		}
		bool operator==(const string& str)const
		{
			return strcmp(_str, str._str) == 0;
		}
		bool operator>=(const string& str)const
		{
			return (*this > str) || (*this == str);
		}
		bool operator<(const string& str)const
		{
			return !(*this >= str);
		}
		bool operator<=(const string& str)const
		{
			return (*this < str) || (*this == str);
		}
		bool operator!=(const string& str)const
		{
			return !(*this == str);
		}


		//[]运算符重载
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		//const对象的[]运算符重载
		const char& operator[](size_t pos)const
		{
			assert(pos < _size);
			return _str[pos];
		}


		void push_back(const char& c)//追加字符
		{
			if (_size + 1 > _capacity)//空间不够需要扩容
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
				//当_capacity为0时,只开辟一个字节,在后面赋值会出现越界访问
			}
			_str[_size] = c;//_size下标位置正好是'\0'的位置,也就是最后一个元素的下一个位置
			_size++;
			_str[_size] = '\0';//别忘记加上'\0'

			//insert(_size, c);
		}

		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+=(const char* str)
		{
			append(str);
			return *this;
		}

		string& operator+=(const char& c)
		{
			push_back(c);
			return *this;
		}
		//void reserve(size_t size);
		void resize(size_t size, const char& c = '\0')
		{
			if (size <= _size)//说明是删除数据,保留前n个
			{
				_str[size] = '\0';
				_size = size;
			}
			else
			{
				if (size > _capacity)//如果size大于容量,就需要扩容
				{
					reserve(size);
				}
				int i = _size;
				while (i < size)
				{
					_str[i++] = c;

				}
				_size = size;
				_str[_size] = '\0';
			}



		}


		void reserve(size_t size)
		{
			if (size > _capacity)//防止缩容
			{
				char* tmp = new char[size + 1];
				strcpy(tmp, _str);//别忘记重新开辟完空间,要把原数据拷贝过来
				delete[] _str;
				_str = tmp;
				_capacity = size;
			}
		}


		void insert(size_t pos, const char& c)//随机插入一个字符
		{
			assert(pos <= _size);
			if (_size + 1 > _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			size_t end = _size + 1;
			while (pos + 1 <= end)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = c;
			_size++;
		}


		void insert(size_t pos, const char* str)//随机插入一个字符串(难点)
		{
			assert(pos <= _size);
			int len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			size_t end = len + _size;
			while (end > pos + len - 1)
			{
				_str[end] = _str[end - len];
				end--;
			}
			strncpy(_str + pos, str, len);
			_size += len;

		}


		void erase(size_t pos, size_t len = npos)//删除任意位置的数据(难点)
		{
			if (len == npos || len + pos >= _size)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}

		 }


		void swap(string& str)//交换,比起库<algorithm>中的swap更高效,减少拷贝构造,赋值重载
		{
			std::swap(_str,str._str);
			std::swap(_size,str._size);
			std::swap(_capacity, str._capacity);
		}


		size_t find(const char& c, size_t pos = 0)const//查找字符
		{
			assert(pos < _size);
			for (int i = pos;i < _size; i++)
			{
				if (_str[i] == c)
				{
					return i;
				}
			}
			return npos;
		}




		size_t find(const char* str, size_t pos = 0)const//查找子串
		{
			assert(pos < _size);
			char* ret=strstr(_str + pos, str);
			if (ret == nullptr)
			{
				return npos;
			}
			return ret - _str;//指针相减,正好是对应下标
		}
		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}
	private:
		char* _str;
		int _size;
		int _capacity;
		static const size_t npos=-1;//特例,并且只允许是整型
		//static const double d = 1.1;//错误
   };
   //const size_t string::npos = -1;//也可以这样

   ostream& operator<<(ostream& out, const string& str)//流提取
   {
	   for (auto e : str)
	   {
		   cout << e;
	   }
	   return out;
   }

   istream& operator>>(istream& in, string& str)//流插入
   {
	   str.clear();//需要对string对象做清理,否则会因为strcpy的原因而导致打印乱码
	   char ch;
	   ch=cin.get();//直接使用cin会跳过' '和换行符
	   char buff[128];//减少调用+=重载
	   int i = 0;
	   while (ch != ' ' && ch != '\n')
	   {
		   buff[i++] = ch;
		   if (i == 127)
		   {
			   buff[i] = '\0';
			   str += buff;
			   i = 0;
		   }
		   ch = cin.get();
	   }

	   if (i != 0)
	   {
		   buff[i] = '\0';
		   str += buff;
	   }



	   return in;
   }
}

🌸🌸string模拟实现的知识大概就讲到这里啦,博主后续会继续更新更多C++的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轩情吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值