【C++]string模拟实现

发布于:2025-05-20 ⋅ 阅读:(22) ⋅ 点赞:(0)
#pragma once
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
using namespace std;
namespace liu
{
	class string
	{
	public:
		using iterator = char*;
		using const_iterator = const char*;
		//string();//无参构造 
		string(const string& s);//拷贝构造
		string(const char* str="");//有参构造
		

		~string();//析构
		
		char& operator[](size_t i)
		{
			assert(i < _size);
			return _str[i];
		}
		 
		const char& operator[](size_t i)const
		{
			assert(i < _size);
			return _str[i];
		}


		size_t size()const
		{
			return _size;
		}

		const char* c_str()const//c_str函数,返回_str
		{
			return _str;
		}

		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str+_size;
		}

		const_iterator begin()const
		{
			return _str;
		}

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

		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}


		void reserve(size_t n);
		void push_back(char ch);
		void append(const char* ch);
		string& operator+=(char ch);
		string& operator+=(const char* ch);

		void insert(size_t pos,char ch);
		void insert(size_t pos,const char* ch);
		void erase(size_t pos,size_t len=npos);



		size_t find(char ch,size_t pos=0);
		size_t find(const char* ch,size_t pos=0);

		string substr(size_t pos = 0, size_t len = npos)const;
		string& operator=(string s);

		void swap(string& s);



	private:
		
		char* _str=nullptr;
		size_t _size=0;
		size_t _capacity=0;

	public:
		//c++的特殊处理
		static const size_t npos=-1;
	};
	void swap(string& s1, string& s2);
	bool operator==(const string& lhs, const string& rhs);
	bool operator!=(const string& lhs, const string& rhs);
	bool operator<(const string& lhs, const string& rhs);
	bool operator>(const string& lhs, const string& rhs);
	bool operator<=(const string& lhs, const string& rhs);
	bool operator>=(const string& lhs, const string& rhs);

	ostream& operator<<(ostream& os,const string& str);
	istream& operator>>(istream& is, string& str);
	istream& getline(istream& is, string& str,char delim='\n');
	
}
#include"string.h"

namespace liu
{
	 //const size_t string:: npos = -1;

	/*string::string()
		:_str(new char[1] {'\0'})
		, _size(0)
		, _capacity(0)
	{}*/

	string::string(const char* str)
		//:_str(new char[strlen(str)+1])//出去字符串的空间,还要保留一个'\0'的空间,所以开辟的空间要加1
		//,_size(strlen(str))
		//,_capacity(strlen(str))
		:_size(strlen(str))
	{
		_str = new char[_size + 1];
		_capacity = _size;

		strcpy(_str, str);
	}

	/*string::string(const string& s)
	{
		_str = new char[s._capacity+1];
		strcpy(_str,s._str);
		_size = s._size;
		_capacity = s._capacity;
	}*/
	string::string(const string& s)
	{
		string tmp(s._str);
		swap(tmp);
	}

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

	void string::reserve(size_t n)
	{
		if (n>_capacity)
		{
			cout << "reserve:" << n << endl;
			char* tmp = new char[n + 1];
			strcpy(tmp,_str);
			delete _str;
			_str = tmp;

			_capacity = n;
		}
	}
	void string::push_back(char ch)
	{
		/*if (_size==_capacity)
		{
			reserve(_capacity==0?4:_capacity*2);
		}
		_str[_size++] = ch;*/
		insert(_size,ch);
	}
	void string::append(const char* ch)
	{
		/*size_t len = strlen(ch);
		if (_size+len>_capacity)
		{
			size_t NewCapacity = 2 * _capacity;
			if (NewCapacity < _size + len)
				NewCapacity = _size + len;
			reserve(NewCapacity);
		}
		strcpy(_str + _size, ch);
		_size += len;*/
		insert(_size,ch);
	}
	string& string::operator+=(char ch)
	{
		push_back(ch);
		return *this;
	}
	string& string::operator+=(const char* ch)
	{
		append(ch);
		return *this;
	}

	void string::insert(size_t pos, char ch)
	{
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
		size_t end = _size+1;
		while (end>pos)
		{
			_str[end] = _str[end-1];
			end--;
		}
		_str[pos] = ch;
		_size++;
	}
	void string::insert(size_t pos, const char* ch)
	{
		assert(pos<=_size);
		size_t len = strlen(ch);
		if (_size + len > _capacity)
		{
			size_t NewCapacity = 2 * _capacity;
			if (NewCapacity < _size + len)
				NewCapacity = _size + len;
			reserve(NewCapacity);
		} 
		size_t end = _size+len;
		while (end>pos+len-1 )
		{
			_str[end] = _str[end-len];
			--end;
		}

		for (size_t i=0;i<len;i++)
		{
			_str[pos + i] = ch[i];
		}
		_size += len;
	}

	void string::erase(size_t pos, size_t len)
	{
		assert(pos<_size);
		if (len>_size-pos)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			size_t end = pos + len;
			while (end<=_size)
			{
				_str[end - len] = _str[end];
				++end;
			}
			_size -= len;
		}
	}

	size_t string::find(char ch, size_t pos)
	{
		assert(pos<_size);
		for (size_t i=pos;i<_size;i++)
		{
			if (ch==_str[i])
			{
				return i;
			}
		}
		return npos;
	}
	size_t string::find(const char* ch, size_t pos)
	{
		const char* ptr = strstr(_str+pos,ch);
		if (ptr==nullptr)
		{
			return npos;
		}
		else
		{
			return ptr - _str;
		}
	}

	string string::substr(size_t pos , size_t len )const
	{
		if (len>(_size-pos))
		{
			len = _size - pos;
		}
		liu::string sub;
		sub.reserve(len);
		for (size_t i=0;i<len;i++)
		{ 
			sub += _str[pos + i];
		}
		return sub;
	}
	//传统写法
	//string& string::operator=(const string& s)
	//{
	//	if (this != &s)
	//	{
	//		delete[] _str;
	//		_str = new char[s._capacity + 1];
	//		strcpy(_str, s._str);
	//		_size = s._size;
	//		_capacity = s._capacity;
	//	}
	//	return *this;
	//}

	 string& string::operator=( string s)
	 {
		/*if (this != &s)
		{	
			string tmp(s._str);
			swap(tmp);
		}*/
		swap(s);
		return *this;
	 }

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


	bool operator==(const string& lhs, const string& rhs)
	{
		return strcmp(lhs.c_str(),rhs.c_str())==0;
	}
	bool operator!=(const string& lhs, const string& rhs)
	{
		return !(lhs == rhs);
	}
	bool operator<(const string& lhs, const string& rhs)
	{
		return strcmp(lhs.c_str(),rhs.c_str())<0;
	}
	bool operator>(const string& lhs, const string& rhs)
	{
		return !(lhs < rhs || lhs == rhs);
	}
	bool operator<=(const string& lhs, const string& rhs)
	{
		return lhs < rhs || lhs == rhs;
	}
	bool operator>=(const string& lhs, const string& rhs)
	{
		return !(lhs < rhs);
	}


	ostream& operator<<(ostream& os, const string& str)
	{
		//os<<"\"";
		//os << '"';
		for (size_t i=0;i<str.size();i++)
		{
			cout << str[i];
		}
		return os;
	}
	istream& operator>>(istream& is, string& str)
	{
		str.clear();
		//str.reserve(1024);
		int i = 0;
		char buff[256];
		char ch;
		ch = is.get();
		while (ch!=' '&&ch!='\n')
		{
			buff[i++] = ch;
			if (i==255)
			{
				buff[i] = '\0';
				str += buff;
				i = 0;
			}
			ch = is.get();
		}
		if (i>0)
		{
			buff[i] = '\0';
			str += buff;
		}
		return is;
	}

	istream& getline(istream& is, string& str, char delim)
	{
		str.clear();
		
		int i = 0;
		char buff[256];
		char ch;
		ch = is.get();
		while (ch != delim)
		{
			buff[i++] = ch;
			if (i == 255)
			{
				buff[i] = '\0';
				str += buff;
				i = 0;
			}
			ch = is.get();
		}
		if (i > 0)
		{
			buff[i] = '\0';
			str += buff;
		}
		return is;
	}

}

构造函数:

 string(const char* str="")//当实例化时,没有给参数,就使用这里的缺省参数,这个参数就相当于给对象赋值了一个'\0'
   	:_size(strlen(str))
{
	_capacity = _size;
	_str = new char[_size + 1];

	strcpy(_str,str);
}


网站公告

今日签到

点亮在社区的每一天
去签到