STL-string使用和模拟实现

在C语言中其实是没有字符串这个类型的,使用字符串的时候用字符数组,在C++中引入了string这个字符串类型,这个类型更加的快捷和方便、我们可以学习如何使用以及了解底层是如何实现的。

使用时包含头文件#include <string>using namespace std
string类的构造函数

string()  //构造空的string对象,空字符
string(const char* s) //用C-string来构造string类
string(size_t n,char c)//用n个字符c来初始化构造string类
string(const string& s)//拷贝构造

string类对象容器的操作

size()	//返回字符串有效字符长度
length() //返回字符串有效字符长度,与size()相同
capacity()//返回空间总大小
empty() //检测字符串是否为空串
clear() //清理有效字符
reserve()//为string类对象预开辟空间
resize()//为string类对象预开辟空间并初始化。

string类对象内容的增删查改函数

push_back()	//在字符串后尾插字符c
append()	//在字符串后追加字符串
operator+=	//在字符串后追加字符串
c_str()		//返回c格式字符串
find()		//从pos位置开始向后查找字符c,然后返回位置
rfind()		//从pos位置开始向前查找字符c,然后返回位置
substr()	//在str中从pos位置开始,截取n个字符,然后将其返回。

string重载了一些运算符操作,例如:

[]>=><<=++====!=<<>>

迭代器的使用

//普通迭代器
string s("hello world");
string::iterator it = s.begin();
while(it!=s.end()){
	cout<<*it<<" ";
	it++;
}
cout<<endl;

//范围for,底层也是迭代器
for(auto& e: s){
	cout<<s<<" ";
}
cout<<endl;

string的模拟实现

class string {
public:
	//迭代器,底层还是char* 类型的指针。
	typedef char* iterator;
	typedef const char* const_iterator;
	
	string(const char* str = "") {
		_a = new char[strlen(str)+16];
		strcpy(_a, str);
		_size = strlen(str);
		_capacity = strlen(str) + 16;
	}
	string(const string& s) {
		_a = new char[s._capacity];
		strcpy(_a, s._a);
		_size = s._size;
		_capacity = s._capacity;
	}
	string& operator=(const string& s) {
		_a = new char[s._capacity];
		strcpy(_a, s._a);
		_size = s._size;
		_capacity = s._capacity;
		return *this;
	}
	~string() {
		delete[] _a;
		_size = _capacity = 0;
	}

	iterator begin() {
		return _a;
	}
	const_iterator begin() const{
		return _a;
	}
	iterator end() {
		return _a + _size;
	}
	const_iterator end() const{
		return _a + _size;
	}
	void push_back(char c) {
		if (_size+1 >= _capacity) {
			reserve(2 * _capacity);
		}
		_a[_size] = c;
		_size++;
		_a[_size] = '\0';
	}

	string& operator+=(char c) {
		push_back(c);
		return *this;
	}

	void append(const char* str) {
		if (_size + strlen(str) > _capacity) {
			reserve(2 * _capacity);
		}
		strcpy(_a + _size, str);
		_size += strlen(str);
	}

	string& operator+=(const char* str) {
		append(str);
		return *this;
	}
	void clear() {
		_a[0] = '\0';
		_size = 0;
	}
	void swap(string& s) 
	{
		std::swap(_a, s._a);
		std::swap(_size, s._size);
		std::swap(_capacity, s._capacity);
	}
	const char* c_str()const 
	{
		return _a;
	}

	size_t size()const
	{
		return _size;
	}
	size_t capacity()const
	{
		return _capacity;
	}
	bool empty()const
	{
		return _size == 0;
	}
	char& operator[](size_t index) {
		return _a[index];
	}
	const char& operator[](size_t index) const{
		return _a[index];
	}

	bool operator<(const string& s) {
		return strcmp(_a, s._a) < 0;
	}
	bool operator<=(const string& s) {
		return *this < s || *this == s;
	}
	bool operator>(const string& s) {
		return strcmp(_a, s._a) > 0;
	}
	bool operator>=(const string& s) {
		return *this > s || *this == s;
	}
	bool operator==(const string& s) {
		return strcmp(_a, s._a) == 0;
	}
	bool operator!=(const string& s) {
		return !(*this == s);
	}
	size_t find(char c, size_t pos = 0)const {
		while (pos < _size) {
			if (c == _a[pos])
				return pos;
			pos++;
		}
		return npos;
	}
	size_t find(const char* s, size_t pos = 0) {
		return strstr(_a, s)-begin();
	}
	string& insert(size_t pos, char c) {
		if (_size >= _capacity)
			reserve(2 * _capacity);
		size_t next = _size+1;
		while (next > pos) {
			_a[next] = _a[next-1];
			--next;
		}
		_a[next] = c;
		_size++;
		return *this;
	}
	string& insert(const char* s, size_t pos) 
	{
		int len = strlen(s);
		if (_size + len >= _capacity) {
			reserve(_size + len + 1);
		}
		size_t next = _size+len;
		while (next >= pos+len) {
			_a[next] = _a[next-len];
			--next;
		}
		strncpy(_a + pos, s,len);
		_size += len;
		return *this;

	}
	string& erase(size_t pos, size_t len=npos) {
		int next = pos + len;
		if (len == npos) {
			_a[pos] = '\0';
			_size = pos;
		
		}
		else {
			/*while (next <= _size) {
				_a[next - len] = _a[next];
				next++;
			}*/
			strcpy(_a + pos, _a + pos + len);
			_size -= len;
		}
		
		return *this;
	}
	void resize(size_t n, char c = '\0') {
		if (n < _size) {
			_a[n] = '\0';
			_size = n;
		}
		else {
			if (n > _capacity)
				reserve(n);
			memset(_a + _size+1, c, n - _size-2);
		}
	}
	void reserve(size_t n) {
		if (n > _capacity) {
			char* tem = new char[n];
			strcpy(tem, _a);
			delete[] _a;
			_a = tem;
			_capacity = n;
		}
	}
	

private:
	char* _a;
	size_t _size;
	size_t _capacity;
	static const size_t npos;
};
const size_t string::npos = -1;
	std::ostream& operator<<(std::ostream& out, const string& s)
	{
		for (auto ch : s) {
			out << ch;
		}
		return out;
	}

	std::istream& operator>>(std::istream& in, string& s) {
		s.clear();
		char ch = in.get();
		//定义一个缓冲区
		char buff[128];
		size_t i = 0;
		while (ch != ' ' && ch != '\n') {
			buff[i++] = ch;
			if (i == 127) {
				buff[127] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}
		//如果最后buff里面还有数据,刷新到类对象里面
		if (buff != 0) {
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}

这就是string类的使用和模拟实现,希望对您有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值