string(三)--实现

大家看了这么久的string了,可能对string的简单实现有兴趣,所以我实现了一个string类的常用接口,大家可以自行查看:

我是分多文件写的:

string.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
#include <string.h>
#include <assert.h>

namespace cx
{
	class string
	{
	public:
		//构造函数:
		string(const char* str = "");//默认值声明时写--string()
		string(const string& s);	
		string(size_t n, char c);
		string(const char* s, size_t n);
		string(const string& str, size_t pos, size_t len = npos);
		//运算符重载构造
		string& operator= (const char* s);	
		string& operator= (char c);	
		//string& operator=(const string& s);
		string& operator=(const string s);
		 //析构函数
		~string();
		//迭代器部分:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		const_iterator begin() const
		{
			return _str;
		}
		iterator end()
		{
			return _str+_size;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		iterator rbegin()
		{
			return end();
		}
		const_iterator rbegin() const
		{
			return end();
		}
		iterator rend()
		{
			return begin();
		}
		const_iterator rend() const
		{
			return begin();
		}

		//capacity:
		inline size_t size()const
		{
			return _size;
		}
		inline size_t length()const
		{
			return _size;
		}
		inline size_t capacity()const
		{
			return _capacity;
		}
		inline bool empty()const
		{
			return _size == 0;
		}
		void reserve(size_t n = 0);
		inline size_t max_size() const
		{
			return -1;
		}
		void clear();		

		//modify:
		string& operator+= (const string& str);
		string & operator+= (const char* s);
		string& operator+= (char c);
		void push_back(char c);
		string& append(const string& str);
		string& append(const string& str, size_t subpos, size_t sublen);
		string & append(const char* s);
		string& append(const char* s, size_t n);
		string& append(size_t n, char c);
		string& erase(size_t pos = 0, size_t len = npos);
		void swap(string& str);
		void pop_back();
		string& replace(size_t pos, size_t len, const string& str);
		string& replace(size_t pos, size_t len, const char* s);
		//      const char* c_str()const;
		
		//access:
		char& operator[] (size_t pos);
		const char& operator[] (size_t pos) const;
		char& at(size_t pos);
		const char& at(size_t pos) const;

		//String operations :
		size_t find(const string& str, size_t pos = 0) const;
		size_t find(const char* s, size_t pos = 0) const;
		size_t find(const char* s, size_t pos, size_t n) const;
		size_t find(char c, size_t pos = 0) const;
		string substr(size_t pos = 0, size_t len = npos) const;

		//Non - member function overloads:
		bool operator<(const string& s);
		bool operator<=(const string& s);
		bool operator>(const string& s);
		bool operator>=(const string& s);
		bool operator==(const string& s);
		bool operator!=(const string& s);

		//友元部分:
		friend ostream& operator<<(ostream& _cout, const cx::string& s);	
		friend istream& operator>>(istream& _cin, cx::string& s);
	private:
		const static size_t npos=-1;//特殊用法
		//static size_t npos;
		char* _str=nullptr;//缺省值
		size_t _size=0;//缺省值
		size_t _capacity=0;//缺省值
	};
};
//static正常用法
//size_t npos = -1;

string.cpp:

#include "string.h"
//构造函数:
cx::string::string(const char* str)//默认值处理空串
{
	//不适合列表初始化,原因在于strlen时间复杂度O(N)
	_size = strlen(str);
	_capacity = _size;
	char* tmp = new char[_size + 1];//new不用检查
	strcpy(tmp, str);
	tmp[_size] = '\0';
	delete[] _str;
	_str = tmp;
}
//传统写法:
//cx::string::string(const string& s)
//{
//	char* tmp = new char[s.size() + 1];
//	strcpy(tmp, s._str);
//	tmp[s.size()] = '\0';
//	delete[] _str;
//	_str = tmp;
//	_capacity = s._capacity;
//	_size = s._size;
//}
//现代写法;
cx::string::string(const string& s)
{
	cx::string tmp(s._str);//拷贝一份临时变量
	swap(tmp);//将*this和tmp交换
	//注意点,this初始化情况,我们在private处给缺省值
}
cx::string::string(size_t n, char c)
{
	char* tmp = new char[n + 1];
	//strcpy(_str, 0);
	_size = n;
	_capacity = n;
	for (int i = 0; i < n; i++)
	{
		tmp[i] = c;
	}
	tmp[_size] = '\0';
	delete[] _str;
	_str = tmp;
}
cx::string::string(const char* s, size_t n)
{
	char* tmp = new char[n + 1];
	strncpy(tmp, s, n);
	tmp[n] = '\0';
	delete[] _str;
	_str = tmp;
	_size = _capacity = n;
}
cx::string::string(const string& str, size_t pos, size_t len)
{
	if (len == npos || pos + len > str._size)
	{
		char* tmp = new char[str.size() - pos + 1];
		_capacity = str.size() - pos;
		strncpy(tmp, str._str + pos, len);
		delete[] _str;
		_str = tmp;
	}
	else
	{
		char* tmp = new char[len + 1];
		_capacity = len;
		strncpy(tmp, str._str + pos, len);
		delete[] _str;
		_str = tmp;
	}
	_size = len;
	_str[_size] = '\0';
}
//运算符重载构造
cx::string& cx::string::operator= (const char* s)
{
	_capacity = _size = strlen(s);
	char* tmp = new char[_size + 1];
	strcpy(tmp, s);
	tmp[_size] = '\0';
	delete[] _str;
	_str = tmp;
	return *this;
}
cx::string& cx::string::operator= (char c)
{
	char* tmp = new char[2];
	tmp[0] = c;
	_size = _capacity = 1;
	tmp[_size] = '\0';
	delete[] _str;
	_str = tmp;
	return *this;
}
//传统写法:
//cx::string& cx::string::operator=(const string& s)
//{
//	if (this != &s)
//	{
//		char* tmp = new char[s._capacity + 1];
//		strcpy(tmp, s._str);
//		tmp[s._capacity] = '\0';
//		delete[] _str;
//		_str = tmp;
//		_size = s._size;
//		_capacity = s._capacity;
//	}
//	return *this;
//}
//现代写法:
cx::string& cx::string::operator=(string s)
{
	swap(s);//将this和s交换
	return *this;
}
//析构函数
cx::string::~string()
{
	delete[] _str;
	_str = nullptr;
	_size = _capacity = 0;
}

//capacity:
void cx::string::reserve(size_t n)
{
	if (n > _capacity)
	{
		char* tmp = new char[n + 1];
		strcpy(tmp, _str);		
		delete[] _str;
		_str = tmp;
		_capacity = n;
	}
}
void cx::string::clear()
{
	erase();
}
void cx::string::swap(string& str)
{
	std::swap(_str, str._str);
	std::swap(_size,str._size);
	std::swap(_capacity , str._capacity);
}
void cx::string::pop_back()
{
	erase(_size - 1, 1);
}
cx::string& cx::string::replace(size_t pos, size_t len, const string& str)
{
	//检查
	if (pos + len > _size)
	{
		reserve(pos + len);
		strncpy(_str + pos, str._str, len);
		_size = pos + len;
		_str[_size] = '\0';
	}
	else
	{
		strncpy(_str + pos, str._str, len);
		_size = pos + len;
	}
	return *this;
}
cx::string& cx::string::replace(size_t pos, size_t len, const char* s)
{
	//检查
	if (pos + len > _size)
	{
		reserve(pos + len);
		strncpy(_str + pos, s, len);
		_size = pos + len;
		_str[_size] = '\0';
	}
	else
	{
		strncpy(_str + pos, s, len);
		_size = pos + len;
	}
	return *this;
}

//modify:
cx::string& cx::string::operator+= (const cx::string& str)
{
	append(str);
	return *this;
}
cx::string& cx::string::operator+= (const char* s)
{
	append(s);
	return *this;
}
cx::string& cx::string::operator+= (char c)
{
	push_back(c);
	return *this;
}
void cx::string::push_back(char c)
{
	if (_capacity == _size)
	{
		size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
		reserve(newcapacity);
	}
	_str[_size++] = c;
	_str[_size] = '\0';
}
cx::string& cx::string::append(const string& str)
{
	if (str._size + _size > _capacity)
	{
		reserve(str._size + _size);
	}
	strcpy(_str + _size, str._str);
	_size += str._size;
	_str[_size] = '\0';
	return *this;
}
cx::string& cx::string::append(const char* s)
{
	size_t len = strlen(s);
	if (len + _size > _capacity)
	{
		reserve(_size + len);
	}
	strcpy(_str + _size, s);
	_size += len;
	_str[_size] = '\0';
	return *this;
}
cx::string& cx::string::append(size_t n, char c)
{
	//检查
	if (n + _size > _capacity)
	{
		reserve(n + _size);
	}
	for (size_t i = _size; i < _size + n; i++)
	{
		_str[i] = c;
	}
	_size += n;
	_str[_size] = '\0';
	return *this;
}
cx::string& cx::string::append(const char* s, size_t n)
{
	//检查
	if (n + _size > _capacity)
	{
		reserve(n + _size);
	}
	strncpy(_str+_size, s, n);
	_size += n;
	_str[_size] = '\0';
	return *this;
}
cx::string& cx::string::append(const string& str, size_t subpos, size_t sublen)
{
	//检查
	if (sublen + _size > _capacity)
	{
		reserve(sublen + _size);
	}
	strncpy(_str+_size, str._str+subpos, sublen);
	_size += sublen;
	_str[_size] = '\0';
	return *this;
}
cx::string& cx::string::erase(size_t pos, size_t len)
{	
	assert(pos <= _size);
	if (len == npos || len + pos > _size)
	{
		_str[pos] = '\0';
		_size = pos;
	}
	else
	{
		strcpy(_str + pos, _str + pos + len);
		_size -= len;
		_str[_size] = '\0';
	}
	return *this;
}

//access:
char& cx::string::operator[] (size_t pos)
{
	assert(pos <= _size);
	return *(_str + pos);//等价于_str[pos]
}
const char& cx::string::operator[] (size_t pos) const
{
	assert(pos <= _size);
	return *(_str + pos);//等价于_str[pos]
}
char& cx::string::at(size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}
const char& cx::string::at(size_t pos) const
{
	assert(pos < _size);
	return _str[pos];
}

//String operations :
size_t cx::string::find(const string& str, size_t pos ) const
{
	char* tmp = new char[str._size + 1];
	strcpy(tmp, str._str);
	tmp[str._size ] = '\0';
	const char* ptr = strstr(_str + pos, tmp);
	if (ptr == nullptr)
	{
		delete[] tmp;
		tmp = nullptr;
		return npos;
	}
	else
	{
		delete[] tmp;
		tmp = nullptr;
		return ptr - _str;
	}
}
size_t cx::string::find(const char* s, size_t pos ) const
{
	const char* ptr = strstr(_str + pos, s);
	if (ptr == nullptr)
	{
		return npos;
	}
	else
	{
		return ptr - _str;
	}
}
size_t cx::string::find(const char* s, size_t pos, size_t n) const
{
	char* tmp = new char[n];
	strcpy(tmp, s);
	tmp[n] = '\0';
	const char* ptr = strstr(_str + pos, tmp);
	if (ptr == nullptr)
	{
		delete[] tmp;
		tmp = nullptr;
		return npos;
	}
	else
	{
		delete[] tmp;
		tmp = nullptr;
		return ptr - _str;
	}
}
size_t cx::string::find(char c, size_t pos ) const
{
	for (size_t i = pos; i < _size; i++)
	{
		if (_str[i] == c)
			return i;
	}
	return npos;
}
cx::string cx::string::substr(size_t pos , size_t len) const
{
	//检查:
	assert(pos < _size);
	size_t end = pos + len;
	if (len == npos || pos + len >= _size)
	{
		end = _size;
	}
	string str;
	str.reserve(end - pos);
	for (size_t i = pos; i < end; i++)
	{
		str += _str[i];
	}
	return str;
}

//Non - member function overloads:
bool cx::string::operator<(const string& s)
{
	size_t n = _size > s._size ? s._size : _size;
	for (size_t i = 0; i < n; i++)
	{
		if (_str[i] >= s._str[i])return false;
	}
	if (n == s._size)return false;
	else
		return true;
}
bool cx::string::operator<=(const string& s)
{
	return !(*this > s);
}
bool cx::string::operator>(const string& s)
{
	return !((*this == s) || (*this < s));
}
bool cx::string::operator>=(const string& s)
{
	return !(*this < s);
}
bool cx::string::operator==(const string& s)
{
	if (_size != s._size)return false;
	for (size_t i = 0; i < _size; i++)
	{
		if (_str[i] != s._str[i])return false;
	}
	return true;
}
bool cx::string::operator!=(const string& s)
{
	return !(*this == s);
}

//友元:
// 写法一:
//namespace cx
//{
//	ostream& operator<<(ostream& _cout, const cx::string& s)
//	{
//		for (auto e : s)
//		{
//			_cout << e;
//		}
//		return _cout;
//	}
//}
//写法二:
ostream& cx::operator<<(ostream& _cout, const cx::string& s)
{
	for (auto e : s)
	{
		_cout << e;
	}
	return _cout;
}
istream& cx::operator>>(istream& _cin, cx::string& s)
{
	s.clear();//清除内容
	char ch = _cin.get();
	//建立一个缓冲数组
	char buff[64];
	size_t i = 0;
	while((ch != ' ') && (ch != '\n'))
	{
		//读入buff中
		buff[i++] = ch;
		if (65 == i)
		{
			buff[i] = '\0';//注意:置零
			s += buff;//利用operator+=数组
			i = 0;
		}
		ch = _cin.get();
	}
	if (i > 0)
	{
		buff[i] = '\0';
		s += buff;
	}
	return _cin;
}

test.cpp:

#include "string.h"
void test_string()
{
	cx::string s0("Initial string");
	std::cout << s0 << std::endl;
	cx::string s1;
	std::cout << s1 << std::endl;
	cx::string s2(s0);
	std::cout << s2 << std::endl;
	cx::string s3(s0, 8, 3);
	std::cout << s3 << std::endl;
	cx::string s4("A character sequence");
	std::cout << s4 << std::endl;
	cx::string s5("Another character sequence", 12);
	std::cout << s5 << std::endl;
	cx::string s6(10, 'x');
	std::cout << s6 << std::endl;
	cx::string s7(10, 42);
	std::cout << s7 << std::endl;
}
void test_operator()
{
	cx::string str("Test string");
	for (int i = 0; i < str.size(); ++i)
	{
		std::cout << str[i] << std::endl;
	}
	for (int i = 0; i < str.length(); ++i)
	{
		std::cout << str[i] << std::endl;
	}
}
void test_capacity()
{
	cx::string str("Test string");
	std::cout << str.max_size() << std::endl;
	std::cout << str.capacity() << std::endl;
}
void test_reserve()
{
	cx::string str("Test string");
	std::cout << str.empty() << std::endl;
	std::cout << str.capacity() << std::endl;
	str.reserve(50);
	std::cout << str.capacity() << std::endl;
}
void _string2()
{
	cx::string s0("Initial string");
	cout << s0 << std::endl;
	cx::string s1;
	cout << s1 << std::endl;
	cx::string s2(s0);
	cout << s2 << std::endl;
	cx::string s3(s0, 8, 3);
	cout << s3 << std::endl;
	cx::string s4("A character sequence");
	cout << s4 << std::endl;
	cx::string s5("Another character sequence", 12);
	cout << s5 << std::endl;
	cx::string s6(10, 'x');
	cout << s6 << std::endl;
	cx::string s7(10, 42);
	cout << s7 << std::endl;
}
void test_s()
{
	cx::string s0("Initial string");
	cx::string s3(s0, 8, 3);
	cout << s3 << std::endl;
}
void test_opertaor()
{
	cx::string s1 = "hello world";
	cx::string s2 = "c";
	cx::string s3 = s1;
	cout << s1 << std::endl;
	cout << s2 << std::endl;
	cout << s3 << std::endl;
}
void test_o()
{
	cx::string str1, str2, str3;
	str1 = "Test string: ";   // c-string
	str2 = 'x';               // single character
	//str3 = str1 + str2;       // string
	cout << str1 << std::endl;
	cout << str2 << std::endl;
}
void test_push()
{
	cx::string s1 = "hello worl";
	s1.push_back('d');
	cout << s1 << std::endl;
}
void test_append()
{
	cx::string str;
	cx::string str2 = "Writing ";
	cx::string str3 = "print 10 and then 5 more";
	str.append(str2);// "Writing "
	cout << str << std::endl;
	str.append(str3, 6, 3);// "10 "
	cout << str << std::endl;
	str.append("dots are cool", 5);// "dots "
	cout << str << std::endl;
	str.append("here: ");// "here: "
	cout << str << std::endl;
	str.append(10u, '.'); // ".........."
	cout << str << std::endl;
}
void test_oper()
{
	cx::string name("John");
	cx::string family("Smith");
	name += " K. ";
	cout << name << std::endl;
	name += family;
	cout << name << std::endl;
	name += '\n';
	cout << name << std::endl;
}
void erase_test()
{
	cx::string s1 = "hello world";
	cout << s1.size() << std::endl;
	cout << s1.capacity() << std::endl;
	cout << s1 << endl;
	s1.clear();
	cout << s1.size() << std::endl;
	cout << s1.capacity() << std::endl;
	cout << s1 << endl;
}
void test_cin()
{
	cx::string s1, s2;
	cin >> s1;
	cout << s1 << endl;
	cin >> s2;
	s1 += s2;
	cout << s1 << endl;
}
void test_stringc()
{
	cx::string s1 = "helloworld";
	cx::string s2(s1);
	cout << s2 << endl;
}
void test_op()
{
	cx::string s1 = "hello world",s2;
	s2 = s1;
	cout << s2 << endl;
}
int main()
{
	test_stringc();
	return 0;
}

最后,感谢大家的支持!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

jiaofi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值