【C++】string

目录

  • 描述
  • 一、 string (标准库)
    • 1.常用接口
      • 构造函数
      • 非成员函数
      • 常用成员函数
      • to_string(C++11)
  • 二、 string 模拟实现
    • 1.默认成员函数
    • 2.容量(capacity)、大小(size)、清理(clear)、[]重载、c_str函数
    • 3.运算符重载
    • 4.迭代器
    • 5.尾插(push_back)、插入(insert)、追加(append)、+=、删除(erase)
    • 6.查找(find)
    • 7.reserve、resize
    • 8.cin、cout

描述

什么是string?
string是表示字符串的字符串类
该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
string在底层实际是:basic_string 模板类的别名,typedef basic_string string;
不能操作多字节或者变长字符的序列。
在使用string类时必须包含头文件 以及using namespace std;
接下来主要讲一些 string 类里所包含的一些常用的方法和函数 例如 构造 赋值 删除 插入、连接字符 获取字符 查询等等

一、 string (标准库)

标准库中的String类
【C++】string_第1张图片
string类的各种接口
【C++】string_第2张图片

1.常用接口

构造函数

定义 功能
string() 默认构造函数。
string(const char *s) 使用 字符串创建一个 string 对象。
string(const string &s) 拷贝构造函数,使用现有字符串创建一个新字符串。

实例:

默认构造
【C++】string_第3张图片

拷贝构造
【C++】string_第4张图片

非成员函数

定义 功能
= 赋值运算符重载,可以使用string对象赋值,常量字符串赋值以及字符赋值
+= 将右侧字符串的副本附加到左侧的 string 对象
+ 返回将两个字符串连接在一起所形成的字符串
[] 可以让string对象像数组那样使用下标法访问字符串
<< 可以使用cout输出流正常打印string对象的内容
关系运算符 用来判断两个string对象的字符串的关系
getline 获取一行字符串,使用cin读取字符串时,通常以空格或者换行符作分割符号,这样导致有的字符串中有空格读不到会当分隔符,使用getline函数可以读取一行字符串,以换行符作为分隔符

实例1:

【C++】string_第5张图片

【C++】string_第6张图片
实例2:

【C++】string_第7张图片

常用成员函数

迭代器类成员函数 功能
begin 返回指向 string 中第一个字符的迭代器
end 返回指向 string 中最后一个字符的下一个位置的迭代器(即’\0’位置)
rbegin 返回指向 string 中最后一个字符的反向迭代器
rend 返回指向 string 中第一个字符前一个位置的反向迭代器(即-1位置)
crbegin 返回指向常量字符串中最后一个字符的反向迭代器(常量字符串使用)
crend 返回指向常量字符串第一个字符前一个位置的反向迭代器(即-1位置)

实例:

正向迭代器
【C++】string_第8张图片

反向迭代器
【C++】string_第9张图片

  

成员函数 功能
capacity() 返回 string 被分配的容量的大小
size() 返回 string 中字符串的长度
clear() 删除 string 中存储的所有字符
empty() 如果 string 为空则返回 true,否则返回 false
append() 将str字符串追加到string末尾位置
push_back() 在string后面尾插一个字符
find() 返回在 string 中找到的 str 字符串的第一个位置。如果没有找到 str,则返回 string 类的静态成员 string::npos(很大的一个数)
rfind() 返回string中最后一个匹配的字符的位置,如果没有找到 str,则返回 string 类的静态成员 string::npos(很大的一个数)
reserve() 调整空间大小,扩容使用,不建议使用减容
resize() 开空间+初始化内容

实例1:
【C++】string_第10张图片

实例2:
【C++】string_第11张图片

to_string(C++11)

任意类型转字符串
【C++】string_第12张图片

二、 string 模拟实现

1.默认成员函数

namespace tzc{
public:
		//默认构造  +   构造
		//使用缺省参数,无参时构造空字符串, 开空间时多给'\0'开一个空间,capacity不包括'\0'
		string(const char* str="")
			:_size(strlen(str))
		{
			//空串初始capacity值为3
			_capacity = _size==0?3:_size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

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

		//析构函数   new出的空间需使用delete释放
		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0; 
		}
private:
		char* _str;
		size_t _size; 
		size_t _capacity;
	};
}

2.容量(capacity)、大小(size)、清理(clear)、[]重载、c_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];
	}
	
	//size函数
	size_t size() const
	{
		return _size;
	}
	
	//capacity函数
	size_t capacity()const
	{
		return _capacity;
	}
	
	//clear函数
	void clear()
	{
		//清除string中的内容
		_str[0] = '\0';  //将第一个位置设置为 \0
		_size = 0;		 //将string的大小改为0
	}
	
	//c_str函数
	const char* c_str()
	{
		return _str;
	}

3.运算符重载

//在写运算符重载时我们可以复用写好的运算符重载减少冗余代码

	bool operator>(const string& s) const
	{
		return strcmp(_str, s._str)>0;
	}
	
	bool operator== (const string& s) const
	{
		return strcmp(_str, s._str)==0;
	}
	
	bool operator>=(const string& s) const
	{
		return *this>s||*this==s;
	}
	
	bool operator<(const string& s) const
	{
		return !(*this>=s);
	}
	
	bool operator<=(const string& s) const
	{
		return !(*this > s);
	}
	
	bool operator!=(const string& s) const
	{
		return !(*this == s);
	}

4.迭代器

	//在string类中
	typedef char* iterator;
	typedef const char* const_iterator;

	//使用指针方式模拟实现迭代器
	//普通迭代器
	iterator begin()
	{
		return _str;
	}
	iterator end()
	{
		return _str + _size;
	}

	//const迭代器
	iterator begin() const
	{
		return _str;
	}
	iterator end() const
	{
		return _str + _size;
	}

5.尾插(push_back)、插入(insert)、追加(append)、+=、删除(erase)

	//进行插入操作的时候都需要检查他的容量是否够用,如果不够需要扩容
	//尾插 
	void push_back(char ch)
	{
		//扩容
		if (_size + 1 > _capacity)
		{
			reserve(_capacity * 2);
		}
		_str[_size] = ch;
		++_size;
	
		_str[_size] = '\0';
	}
	//push_back 和append可以复用insert
	//追加
	void append(const char* str)
	{
		size_t len = strlen(str);
		if (_size + len > _capacity)
		{
			//扩容
			reserve(_size + len);
		}
		strcpy(_str + _size, str);
		//strcat(_str, str);  //不推荐,自己找 \0 
		_size += len;
		_str[_size] = '\0';
	}
	//
	string& operator+=(const char ch)
	{
		push_back(ch);
		return *this;
	}
	string& operator+=(const char* str)
	{
		append(str);
		return *this;
	}
	
	//可以在指定位置插入字符
	string& insert(size_t pos, char ch)
	{
		if (_size + 1 > _capacity)
		{
			reserve(2 * _capacity);
		}
		size_t end = _size+1;  //end指向\0
		while (end > pos)
		{
			_str[end] = _str[end-1];
			--end;
		}
	
		_str[pos] = ch;
		++_size;
		return *this;
	}
	
	//指定位置插入字符串
	string& insert(size_t pos,const char* str)
	{
		assert(pos <= _size); 
	
		size_t len = strlen(str);
		if (len + _size > _capacity)reserve(len + _size);
	
		size_t end = len + _size;
		while (end >= pos + len)
		{
			_str[end] = _str[end - len];
			--end;
		}
		strncpy(_str + pos, str, len);
		_size += len;
		return *this;
	}
	
	//删除从pos位置开始的len个字符,如果len未传值,则默认从pos位置后面全部删除
	string& erase(size_t pos,size_t len=npos)
	{
		//断言检查pos不得超过字符串的长度
		assert(pos < _size);
		if (len == npos || pos + len >= _size)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			strcpy(_str + pos, _str + pos + len);
			_size -= len;
		}
		return *this;
	}

6.查找(find)

	//从pos位置开始查找指定字符,pos默认为0,也可以指定从什么位置开始查找,如果查找到返回字符所在位置,
	size_t find(char ch,size_t pos=0)
	{
		assert(pos < _size);
		for (size_t i = pos; i < _size; i++)
		{
			if (_str[i] == ch)
			{
				return i;
			}
		}
	}
	
	//从指定位置查找字符串,查找到返回字符串位置
	size_t find(const char* str, size_t pos = 0)
			{
				assert(pos < _size);
				
				char*  ret=strstr(_str + pos, str);
				
				if (ret == nullptr)
				{
					return npos;
				}
				else
				{
					return ret - _str;
				}
			}

7.reserve、resize

	//如果传入的n小于原来的size,则进行缩容(删除数据,申请的空间大小不变)
	void resize(size_t n,char ch='\0')
	{
		//开空间+初始化    
		if (n <= _size)
		{
			//删除数据 缩容,保留前n个
			_size = n;
			_str[n] = '\0';
		}
		else
		{
			//如果传入的n比字符串容量大,则需要申请更大的空间
			if (n > _capacity)
			{ 
				reserve(n);
			}
			while (_size < n)
			{
				//将申请的空间赋值为传入的ch
				_str[_size] = ch;
				_size++;
			}
			_str[_size] = '\0';
		}
	}

	void reserve(size_t n)
	{
		//开空间
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			strcpy(tmp, _str);
			delete[] _str;
			_str = tmp;
			_capacity = n;
		}
	}

8.cin、cout

	//类外函数,避免传入的this占用第一个参数
	ostream& operator<<(ostream& out, const string& s)
	{
		for (auto ch : s)
		{
			cout << ch;
		}
		return out;
	}

	istream& operator>>(istream& in, string& s)
	{
		//getline函数实现同理
		s.clear();  //覆盖原来的数据
		char ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			ch=in.get();
		}
		return in;
	}

你可能感兴趣的:(C++,c++,开发语言)