C++入门-程序员修炼手册-模拟实现string类

#pragma once
#include
#include
#include

using namespace std;
namespace jy  //避免了命名污染
{
	//支持增删查改
	class string
	{
	public:
		string(const char *str = "")//构造函数
		{
			_size = strlen(str);
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}


		//针对类的交换函数
		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}

		//s1(s2)
		string(const string& s)
			:_str(nullptr) //很重要,出了作用域,析构tmp,可以析构NULL,但不能析构随机值。
			, _size(0)
			, _capacity(0)
		{
			string tmp(s._str);
			swap(tmp);
		}


		//运算符重载=
		//s1=s2
		string& operator =(string s)
		{
			swap(s);
			return *this;
		}
		
		//[]重载,在调用时,会优先选择匹配度更高的函数实现
		//返回类型operator运算符(参数列表)
		const char& operator[](size_t i) const//只读
		{
			assert(i < _size);
			return  _str[i];
		}
		char& operator[](size_t i)//可读可写
		{
			assert(i < _size);
			return  _str[i];
		}

		//for循环遍历
		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}

		//请求将字符串容量调整为计划的大小更改,以达到最多 n 个字符的长度
		void reserve(size_t n )
		{
			if (n > _capacity)
			{
				char*tmp = new char[n + 1];
				strncpy(tmp, _str,_size+1);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}

		// 开空间+并且初始化空间。size也要始化,扩展capacity
		//resize(10,hello)
			//resize()用来将字符串大小调整为n个字符的长度。
			//如果 n 小于当前字符串长度,则将当前size缩短为n。
			//如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,
			//以达到 n 的大小。 如果指定了字符,则将新元素初始化为该字符,否则初始化为空字符
		void resize(size_t n,  char  val= '\0')
		{
			if (n < _size)
			{
				_size = n;
				_str[_size] = '\0';
			}
			else
			{
				if (n > _capacity)
				{
					reserve(n);
				}
				for (size_t i = 0; i < n; ++i)
				{
					_str[i] = val;
				}
				_str[n] = '\0';
				_size = n;
			}
		}
		//+=运算符重载 s1+=x
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		//+=运算符重载 s1+=xhasdgasd
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}
		//尾插数据,需要用reverse和reserve
		void push_back(char ch)
		{
			/*if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			_str[_size] = ch;
			_str[_size + 1] = '\0';
			++_size;*/
			insert(_size, ch);
		}
		//追加字符串
		void append(const char* str)
		{
			/*size_t len = strlen(str) + _size;
			if (len > _capacity)
			{
				reserve(len);
			}
			strcpy(_str + _size, str);
			_size = len;*/
			insert(_size, str);
		}
		//插入数据
		string& insert(size_t pos, char ch)
		{
			assert(pos <= _size);//防止插入位置大于字符串数据长度
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);//防止capacity为空
			}
			char* end = _str + _size;
			while (end >= _str + pos)
			{
				*(end + 1) = *end;
				--end;
			}
			_str[pos] = ch;
			_size++;
			return *this;
		}
		string& insert(size_t pos,const char* str)//插入字符串
		{
			assert(pos <= _size);//防止插入位置大于字符串数据长度
			size_t len=strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			char* end = _str + _size;
			while (end>=_str+pos)
			{
				*(end + len) = *end;
				--end;
			}
			strncpy(_str + pos, str,len);
			_size += len;
			return *this;
		}
		//返回size
		size_t size() const
		{
			return _size;
		}
		//返回容量
		size_t capacity() const
		{
			return _capacity;
		}

		//析构函数
		~string()
		{
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
		}
		//c_str
		const char* c_str() const
		{
			return _str;
		}
		
		//删除一定长度字符
		string& erase(size_t pos, size_t len = npos)
		{
			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;
		}
		//find一个字符函数
		size_t find(const char ch,size_t pos=0) const 
		{
			assert(pos < _size);
			for (size_t i = 0; i < _size; i++)
			{
				if (ch == _str[i])
				{
					return i;
				}
			}
			return npos;
		}
		//find一个字符串函数
		size_t find(char*str, size_t pos=0) const 
		{
			assert(pos < _size);
			const char* ret = strstr(_str + pos, str);
			if (ret)
			{
				return ret - _str;
			}
			else
			{
				return npos;
			}
		}
		// rfind  可以下去尝试思想如何用比较简单的方式搞出来
		void clear()
		{
			_size = 0;
			_str[0] = '\0';
		}
	private:
		char*  _str;
		size_t _size;
		size_t _capacity;
		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(const string& s1, const string& s2)
	{
		return !(s1 <= s2);
	}
	inline bool operator>=(const string& s1, const string& s2)
	{
		return !(s1>(istream& in, string& s)
	{
		s.clear();
		char ch;
		//in << ch;不能用它的原因在于会吞掉"\n",导致字符串后面没有\0
		ch = in.get();
		while (ch != ' '&& ch != '\n')
		{
			s += ch;
			ch = in.get();
		}
		return in;
	}
	istream& getline(istream& in, string& s)
	{
			s.clear();
			char ch;
			ch = in.get();
			while (ch != '\n')
			{
				s += ch;
				ch = in.get();
			}
		return in;
	}

	//void test_string3()
	//{
	//	string s2("hello Etta");
	//	string::iterator it = s2.begin();
	//	while (it != s2.end())
	//	{
	//		cout << *it << "";
	//		it++;
	//	}
	//	cout << endl;
	//	// 看起来很神奇,但是原理很简单,这个范围for会被编译器替换成迭代器形式
	//	// 也就是说范围for是有迭代器支持的
	//	for (auto e : s2)
	//	{
	//		cout << e << "";
	//	}
	//	cout << endl;
	//}
	//void test_string4()
	//{
	//	string s1("hello world");
	//	s1 += '#';
	//	for (auto ch : s1)
	//	{
	//		cout << ch << " ";
	//	}
	//	cout << endl;

	//	s1 += "xyz";
	//	for (auto ch : s1)
	//	{
	//		cout << ch << " ";
	//	}
	//	cout << endl;

	//	s1 += "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1";
	//	for (auto ch : s1)
	//	{
	//		cout << ch << " ";
	//	}
	//	cout << endl;
	//}
	//void test_resize()
	//{
	//	string s1("hello world");
	//	s1.resize(5, 'x');
	//	for (auto ch : s1)
	//	{
	//		cout << ch << " ";
	//	}
	//	cout << endl;
	//}
	//void test_string6()
	//{
	//	string s1("hello");
	//	s1.insert(2, 'x');
	//	cout << s1.c_str() << endl;

	//	s1.insert(0, 'y');
	//	cout << s1.c_str() << endl;

	//	s1.insert(0, "!!!!");
	//	cout << s1.c_str() << endl;

	//	s1 += '!';
	//	cout << s1.c_str() << endl;

	//	s1 += "world";
	//	cout << s1.c_str() << endl;

	//	s1.erase(2, 5);
	//	cout << s1.c_str() << endl;

	//	s1.erase(2);
	//	cout << s1.c_str() << endl;
	//}
	/*void test_find()
	{
		string s2("hello Etta");
		cout< s2)<> s2;
		//cout << s2;
		getline(cin, s2);
		cout << s2;
	     cout <

函数调用:测试接口

#define _CRT_SECURE_NO_WARNINGS
#include"string.h"
int main()
{
	/*jy::string s1("hello Etta");
	jy::string s2(s1);
	jy::string s3;
	s3 = s1;
	s3.resize(10);
	cout << s3.c_str()<< endl;*/
	//jy::test_string4();
	//jy::test_string3();
	//jy::test_resize();
	//jy::test_string6();
	//jy::test_find();
	//jy::test_cmp();
	jy::test_ostream();
	return 0;
}

你可能感兴趣的:(C++,c++)