C++ STL容器之string--常用接口

学前必须掌握知识

string字符串是表示字符序列的类,标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性。string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;

使用string类,需要引入头文件< string >

学习string接口之前,我们必须知道什么是迭代器
迭代器是一种设计模式,是元素访问的一种设计模式,所有容器都是需要遵循相同的设计规范。例如手机的充电线,我们常用的type-c接口,无论是哪个厂商生产的,你手机只要支持type-c充电线,都可以充电。而迭代器的使用方式都是一样的那如何使用呢?

迭代器的使用方式和指针类似
1、begin迭代器:指向第一个元素的位置
2、end迭代器:指向最后一个元素的下一个位置
3、访问数据方式:*->
4、迭代器的移动:++移动到下一个元素的位置;–移动到上一个元素的位置
5、迭代器支持比较:!===

特殊的反向迭代器
1、rbegin迭代器:指向最后一个元素的位置
2、rend迭代器:指向第一个元素的前一个位置

string类对象的常见构造

功能:构造一个字符串对象,根据所使用的构造函数版本来初始化其值

string() 创建一个空对象
string (const string& str) 拷贝一个字符串对象
string (const char* s) 给予字符串常量来创建字符串
string (const string& str, size_t pos, size_t len = npos) 截取字符串str,从pos位置开始截取len个
string (const char* s, size_t n) 给予字符串常量并从头开始截取n个字符来创建字符串对象
string (size_t n, char c) 创建字符串,内容为n个字符c
string& operator= (const string& str) 给予字符串常量来创建字符串
string& operator= (const char* s) 拷贝一个字符串对象

void test()
{
	string str; // ""
	string copy(str); // ""
	string str2("White"); // "White"
	string substr(str2, 1, 2); //"hi"
	string str3("White ShirtI", 5);//white
	string str4(5, 'w'); //"wwwww"
	str3 = "White ShirtI"; //"White ShirtI"
	str4 = str3; //"White ShirtI"
}

常见的访问字符串操作

char& operator[] (size_t pos)和数组一样通过下标去访问字符串内容,并且可以修改字符串内容(越界会报断言错误)
const char& operator[] (size_t pos) const和上面接口一样,但是不能修改字符串的内容
char& at (size_t pos) 与[]一样通过索引访问字符串,且可以修改字符串内容(越界会抛异常)
const char& at (size_t pos) const 和上面接口一样,但是不能修改字符串的内容
char& front() 访问字符串第一个有效字符,可修改
const char& front() const 访问字符串第一个有效字符,不可修改
char& back() 访问字符串最后一个有效字符,可修改
const char& back() const 访问字符串最后一个有效字符,不可修改

void test()
{
	string str = "White shirtI";
	char& ref = str[7];
	ref = 'S'; //ok
	str.at(0) = 'w'; //ok

	const string str2 = "White ShirtI";
	const char& ref2 = str2[0];
	ref2 = 'w';  //error 表示必须是可修改的左值
	str2.at(0) = 'w';//error 表示必须是可修改的左值
}

string中迭代器的使用

正向迭代器
iterator begin() 指向字符串第一个有效元素,并可以修改
const_iterator begin() const 指向字符串第一个有效元素,不能修改
iterator end() 指向字符串最后一个有效元素的下一个位置,并可以修改
const_iterator end() const 指向字符串最后一个有效元素的下一个位置,不能修改

void test()
{
	string str = "WhiteShirtI";
	string::iterator it = str.begin();
	for (; it != str.end(); ++it)
	{
		cout << *it; //WhiteShirtI
		*it = 'w';
	}

	const string str2 = "WhiteShirtI";
	string::const_iterator it2 = str.begin();
	for (; it != str.end(); ++it)
	{
		cout << *it2;
		*it2 = 'w'; // error 表达式必须为可修改的左值
	}
}

反向迭代器
reverse_iterator rbegin() 指向字符串最后一个有效字符的位置,并且能修改
const_reverse_iterator rbegin() const指向字符串第一个有效字符的位置,不能修改
reverse_iterator rend() 指向字符串第一个有效位置的前一个位置,并且能修改
const_reverse_iterator rend() const 指向字符串第一个有效位置的前一个位置,不能修改

void test()
{
	string str = "12345";
	string::reverse_iterator rit = str.rbegin();
	while (rit != str.rend())
	{
		cout << *rit << " "; //5 4 3 2 1
		*rit = 'w';
		//反向迭代器,什么都是反的
		++rit;
	}

	const string str2 = "12345";
	string::const_reverse_iterator rit2 = str2.rbegin();
	while (rit2 != str2.rend())
	{
		cout << *rit2 << " "; //5 4 3 2 1
		*rit2 = 'w';//error 表达式必须为可修改的左值
		//反向迭代器,什么都是反的
		++rit2;
	}
}

遍历字符串可以通过数组方式通过下边遍历,也可以通过范围for来遍历,范围for底层也是通过迭代器来实现的,获取头尾元素以及迭代器的自增

void test()
{
	string str = "WhiteShirtI";
	for (const auto& ch : str)
	{
		cout << ch;
	}
}

string有关容量的常见接口

size_t size() const 获取有效字符的个数
size_t length() const 获取有效字符的个数
void resize (size_t n) 修改有效字符的个数,如果修改后比原有的有效字符个数多,多出的部分都置为字符’\0’(’\0’并非为有效字符的结束标志,这里’\0’也是有效字符串的其中一个)
void resize (size_t n, char c) 修改有效字符的个数,如果修改后比原有的有效字符个数多,多出的部分都置为字符c

void test()
{
	string str = "White";
	cout << str.size() << endl;
	cout << str.length() << endl;
	str.resize(10);
	cout << str.size() << endl;
	str.resize(2);
	cout << str.size() << endl;

	string str2 = "Shirt";
	cout << str.size() << endl;
	str2.resize(10, 'I'); //"ShirtIIIII"
	cout << str.size() << endl;
	str2.resize(5, 'I'); //有效字符为5,后面参数不起作用
}

在这里插入图片描述
capacity为已经开辟的空间大小容量,当前string中最多可以存放的元素个数,增容规则:增容到原来容量的1.5倍。
size_t capacity() const 获得字符串的容量
void reserve (size_t n = 0) 修改字符串的容量(只能调大不能调小,调小相当于没修改)

void test()
{
	string str = "White";
	cout << str.capacity() << endl; //默认为15
	cout << str.size() << endl; //5
	//修改容量不会影响有效元素个数
	str.reserve(30);
	cout << str.capacity() << endl; //30以上
	cout << str.size() << endl; //5
	//修改有效元素个数会影响容量,并且 cap > size
	str.resize(60);
	cout << str.capacity() << endl; //60以上
	cout << str.size() << endl; //60
}

在这里插入图片描述
void clear() 清空有效字符,置size为0,但不影响容量大小
bool empty() const 判断字符串是否为空,为空返回NULL
void shrink_to_fit() 缩小容量为适合size的大小,优化。

void test()
{
	string str = "White";
	cout << str.size() << endl;
	str.clear();
	cout << str.size() << endl;

	str.reserve(1000);
	cout << str.capacity() << endl;
	str.shrink_to_fit();
	cout << str.capacity() << endl;
}

在这里插入图片描述

常见修改string字符串的接口

string& operator+= (const string& str) 在原来字符的后面添加str字符串的内容
string& operator+= (const char* s) 在原来字符的后面添加常量字符串s
string& operator+= (char c) 在原来字符的后面添加常量字符c

void test()
{
	string str;
	string str2 = "abc";
	str += str2; //"abc"
	str += "def"; //"abcdef"
	str += 'g';//"abcdefg"
}

string& append (const string& str) 追加一个字符串的内容
string& append (const string& str, size_t subpos, size_t sublen)追加一个字符串的内容,从该字符串的第subpos位置起追加sublen个字符
string& append (const char* s) 追加一个常量字符串
string& append (const char* s, size_t n) 追加一个常量字符串的前n个
string& append (size_t n, char c) 追加n个字符c
template <class InputIterator> string& append (InputIterator first, InputIterator last) 从一个字符串的first位置追加到last位置

void test()
{
	string str;
	string str2 = "abc"; 
	str.append(str2);//"abc"
	str.append(str2, 1, 2);//"abcbc"
	str.append("abc"); //"abcbcabc"
	str.append("123456789", 6);//"abcbcabc123456"
	str.append(5, 'w'); // "abcbcabc123456wwwww"

	char arr[] = "abc";
	str.append(arr, arr + sizeof(arr) / sizeof(arr[0])); //"abcbcabc123456wwwwwabc"
	str.append(str2.begin(), str2.end()); //"abcbcabc123456wwwwwabcabc"
}

string& assign (const string& str) 将内容修改为与str内容一样
string& assign (const string& str, size_t subpos, size_t sublen) 将内容修改为str字符串从subpos位置起添加sublen个字符
string& assign (const char* s) 将内容修改为与常量字符串内容一样
string& assign (const char* s, size_t n) 将内容修改为常量字符串的前n个
string& assign (size_t n, char c) 将内容修改为n个字符c
template <class InputIterator> string& assign (InputIterator first, InputIterator last)将字符内容设置为从first位置带last位置的内容一样

void test()
{
	string str;
	string str2 = "abc";
	str.assign(str2); //abc
	str.assign(str2, 1, 2);// bc
	str.assign("abc"); //abc
	str.assign("abcde", 4); //abcd
	str.assign(5, 'w'); //wwwww
	str.assign(++str2.begin(), str2.end()); // bc
}

string& insert (size_t pos, const string& str)在pos位置前插入字符串str的内容
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen) 在pos位置前插入字符串subpos位置起sublen个字符
string& insert (size_t pos, const char* s)在pos位置前插入常量字符串s的内容
string& insert (size_t pos, const char* s, size_t n)在pos位置前插入常量字符串s的n个字符
string& insert (size_t pos, size_t n, char c)在pos位置前添加n个字符c
void insert (iterator p, size_t n, char c)在迭代器之前插入n个字符c
template <class InputIterator> void insert (iterator p, InputIterator first, InputIterator last)在迭代器p位置之前插入first到last迭代器的内容


void test()
{
	string str = "123";
	string str2 = "abc";
	str.insert(0, str2);//abc123
	str.insert(3, str2, 1, 1);//abcb123
	str.insert(str.size(), "www"); // abcb123www
	str.insert(7, "abc", 2);//abcb123ab3www
	str.insert(str.size(), 5, 'a');//abcb123ab3wwwaaaaa
	str.insert(str.begin(), 2, '1');//11abcb123ab3wwwaaaaa
	str.insert(str.end(), str2.begin(), str2.end());//11abcb123ab3wwwaaaaaabc
}

string& erase (size_t pos = 0, size_t len = npos) 从pos位置开始删除,删除npos个元素
iterator erase (iterator p) 删除迭代器所指向的位置的元素
iterator erase (iterator first, iterator last) 删除first到last之间的元素

void test()
{
	string str = "Hello WhiteShirtI";
	str.erase(1, 2);//"Hlo WhiteShirtI"
	str.erase(str.begin());//"lo WhiteShirtI"
	str.erase(++str.begin(), --str.end());//"II"
}

string& replace (size_t pos, size_t len, const string& str) 将pos位置开始,共len个元素全部替换成str
string& replace (size_t pos, size_t len, const string& str,size_t subpos, size_t sublen) 将pos位置开始,共len个元素全部替换成str中从subpos位置开始,sublen个元素
void swap (string& str) 调用者与str交换内容
void pop_back() 删除最后一个元素

void test()
{
	string str = "abc";
	string str2 = "123";
	str.replace(0, 1, str2);//123bc
	str.replace(0, 1, str2, 0, 2);//1223bc
	str.swap(str2); //str:123  str2:1223bc
	str.pop_back();//12
}

常见的string查找元素接口

const char* c_str() 返回一个C语言中带有\0的字符串的首地址
size_t find (const string& str, size_t pos = 0) const 查找一个字符串,从pos位置开始,找到字符串的第一个位置
size_t find (const char* s, size_t pos = 0) 查找一个常量字符串,从pos位置开始,找到字符串的第一个位置
size_t find (const char* s, size_t pos, size_t n)查找一个常量字符串,从pos位置开始,匹配常量字符串的前n个字符就可以,返回第一个字符的位置
size_t find (char c, size_t pos = 0) const 查找字符c,返回第一次查到的位置
rfind与上面函数类似,也有4个接口,从后往前找

void test()
{
	char* c = new char[20];
	string str = "abc";
	strcpy(c, str.c_str()); //c:"abc\0"
	string str2 = "123abc123abc";
	int pos = str2.find(str, 1); //3
	pos = str2.find("bc", 1);//4
	pos = str2.find("bcd", 1, 3); //-1
	pos = str2.find("bcd", 1, 2); //4
	pos = str2.find('c', 0); //5

	pos = str2.rfind(str);//9
	pos = str2.rfind("bc");//10
	pos = str2.rfind("bcd", str2.size(), 3); //-1
	pos = str2.rfind('b'); // 10
}

size_t find_first_of (const char* s, size_t pos, size_t n) 从前往后找,找到s中能匹配n个字符的位置,返回第一次遇到的位置
size_t find_last_of (const char* s, size_t pos, size_t n) const 从后往前,找到s中能匹配n个字符的位置,返回第一次遇到的位置
size_t find_first_not_of (const char* s, size_t pos = 0) 从前往后找,找到的第一个不出现在s中的第一个字符
size_t find_last_not_of (const char* s, size_t pos = npos) 从后往前找,找到的第一个不出现在s中的第一个字符
string substr (size_t pos = 0, size_t len = npos) const 从pos位置开始截取len个字符串,赋予新的字符串

void test()
{
	//size_t find_first_of (const string& str, size_t pos = 0) const
	string str = "abccba123abccba";
	int pos = str.find_first_of("fbfc", 0, 2);//1
	pos = str.find_last_of("fffb"); //13
	pos = str.find_first_not_of("abc");//6
	pos = str.find_last_not_of("abc");//8

	string substr = str.substr(3, 3);//cba
	//使用find与substr获得网站的域名
	str = "https://blog.csdn.net/qq_44443986?spm=1011.2124.3001.5113";
	int pos1 = str.find("://");
	int pos2 = str.find("net");
	substr = str.substr(pos1 + 3, pos2 - pos1);//blog.csdn.net
}

字符串常用的输入输出流

istream& operator>> (istream& is, string& str) 与内置类型一样去输入字符串,以换行为结束
istream& getline (istream& is, string& str)与内置类型一样去输入字符串,以换行为结束
istream& getline (istream& is, string& str, char delim) 与上面函数相似,但是可以指定输入结束标志
ostream& operator<< (ostream& os, const string& str)像内置类型一样输出字符串的内容

void test()
{
	string str;
	cin >> str; //换行结束
	getline(cin, str); //换行结束
	//输入WhirtShirtI
	getline(cin, str, 'S'); //White
	cout << str << endl;//White
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

WhiteShirtI

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

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

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

打赏作者

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

抵扣说明:

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

余额充值