Bootstrap

C++ string类中函数的使用方法

          **难受的一天从读英文文档开始**

在这里插入图片描述

1.默认成员函数

在这里插入图片描述

1.1构造函数

构造函数的重载函数如下:
在这里插入图片描述

int main()
{
	//	1.string();
	//  无参的构造函数
	string s1;
	cout << s1 << endl;

	//	2.string(const char* s);
	//  用一个字符串初始化 s2
	string s2("abcdefgh");
	cout << s2 << endl;

	//	3.string(const string & str);
	//  用一个类构造 s3
	string s3(s2);
	cout << s3 << endl;

	//	4.string(const string & str, size_t pos, size_t len = npos);
	//  从 str 的 pos 下标的位置开始, 向后取 len 个字符 初始化 s4  
	string s4(s2, 4,3);
	cout << s4 << endl;
	//  npos 默认值为 -1   -1转化为无符号类型是一个特别大的整数 2的31次方
	//  因为len的缺省值是npos
	//  第三个参数不传值,会把 str 从 pos开始向后 到 \0 前的所有字符拷贝到 s5
	string s5(s2, 0);
	cout << s5 << endl;

	//	5.string(const char* s, size_t n);
	//  用字符串 s 的前 n 个字符初始化 s6
	string s6("abcdexyz",7);
	cout << s6 << endl;
	// 这里要与 75 行的代码区分开,75行的第一个形参是string类型的类,
	// 这个函数的第一个参数是一个字符串

	//	6.string(size_t n, char c);
	//  用 n 个 c 字符初始化 s7
	string s7(7,'x');
	cout << s7 << endl;

	return 0;
}

在这里插入图片描述

1.2析构函数与赋值函数

析构函数由系统自动调用,也不需要传参数
赋值函数的三种重载方式:
在这里插入图片描述
看参数就知道它可以赋值string类,字符串,单个字符

int main()
{
	string s1;
	string s2("abcdefgh");

	s1 = s2;
	cout << s1 << endl;
	s1 = "xxxxx";
	cout << s1 << endl;
	s1 = 'c';
	cout << s1 << endl;
	return 0;
}

在这里插入图片描述

2.迭代器iterator

在这里插入图片描述

2.1begin

在这里插入图片描述
它的返回值是 iterator 迭代器,如果是const对象,那它的返回类型就是const_iterator
如果const对象调用begin()函数,那它的返回值一定要写成const_iterator,权限可以缩小但不可以放大
在这里插入图片描述
正确写法:

	string s1("abcdefgh");
	const string s2(s1);

	string::iterator it1 = s1.begin();
	string::const_iterator it2 = s2.begin();

2.2 end

在这里插入图片描述
endbegin的返回类型相同,它是指向有效数据的下一个位置
它们结合起来的使用方法:

	string s1("abcdefgh");
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		(*it1)++;
		it1++;
	}
	cout << s1 << endl;

在这里插入图片描述


	string s1("abcdefgh");
	//用s1的begin+3位置开始,到begin+4位置的前一个字符,构造s2
	string s2(s1.begin() + 3, s1.begin()+4);
	cout << s2 << endl;

在这里插入图片描述

2.3 rbegin与rend

在这里插入图片描述
在这里插入图片描述
rbegin就是结尾的第一个数据,rend就是开头的前一个字符。
而且rbegin的++,就是向前移动。rend的–是向后移动。

	string s1("abcdefgh");
	string::reverse_iterator it1 = s1.rbegin();
	cout << *it1 << endl;
	
	string::reverse_iterator it2 = s1.rend();
	cout << *(it2-1) << endl;

在这里插入图片描述
使用场景:我们想要逆序输出string的所有数据

	string s1("abcdefgh");
	string::reverse_iterator it1 = s1.rbegin();
	while (it1 != s1.rend())
	{
		cout << *it1 << ' ';
		it1++;
	}
	cout << endl;

在这里插入图片描述
当一个const string 类型的对象 调用 rbeginrend它的返回值分别为reverse_iteratorconst_reverse_iterator

2.4cbegin,cend,crbegin,crend

cbegin,cend相当于返回类型为const_iteratorbeginend

在这里插入图片描述
在这里插入图片描述

crbegin,crend相当于返回类型为const_reverse_iteratorrbeginrend

在这里插入图片描述
在这里插入图片描述

3.capacity容量

在这里插入图片描述

这些函数比较简单,基本上看一下就知道它怎么使用了

	string s1("abcdefgh");
	
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.max_size() << endl;
	cout << s1.capacity() << endl;
	s1.clear();
	cout << s1 << endl;
	cout << s1.empty() << endl;

在这里插入图片描述

resize与reserve

1.基本使用方法

在这里插入图片描述

resize
1.传一个参数意思是可以把它的长度扩大或缩小
2.传两个参数,第一个参数是要修改size的大小,第二个参数是如果size扩大了,把扩大的内容都初始化为第二个参数

string s1("abcdefgh");
	cout << s1.size() << endl;
	
	s1.resize(50,'c');
	cout << s1 << endl;

	s1.resize(50);
	cout << s1.size() << endl;
	
	s1.resize(5, 'c');
	cout << s1 << endl;

在这里插入图片描述

在这里插入图片描述
reserve改变对象的容量,但它相当于是给编译器一个建议,也可能不会修改容量
它可以扩容也可以缩容,但这需要我们自己来观察容量,不同编译器下它的扩容和缩容规则不一样。

在这里插入图片描述

为什么是这样呢,这与编译器有关,我使用的的vs2019
这个编译器的扩容规则是,第一次扩容是×2倍的容量,后面的扩容是×1.5倍的容量,
缩容也是有消耗的,需要先释放掉原来的空间,在从新申请空间,来保存有效数据
那为什么第一次缩容失败了,第二次却成功了?
实际上编译器在初始化s1时多开辟了空间,其中多开的空间中有一个16个字节的字符数组,
因为申请空间是有消耗的所以如果初始化时的空间小于16就把数据存在数组中,如果大于16才会去开辟空间

在这里插入图片描述
在这里插入图片描述
这里的buf数组就是string类在我们创建对象时开辟的

reverse的使用场景:知道之后的程序需要多少空间,一次性直接开辟好,之后不需要扩容,因为扩容可能也会有消耗。

	string s1;
	s1.reserve(200);
	cout << s1.capacity() << endl;

在这里插入图片描述

它们两的关联

结论:resize 的扩大可能会影响 容量capacity
reserve 不管是扩大还是缩小容量都不会改变resize

string s1;
	s1.reserve(200);
	s1 = "1111111111111111111111111";
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;

	s1.resize(500);
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;

	s1.reserve(10);
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;

在这里插入图片描述

4.Element access数据的存取

在这里插入图片描述

operator【】是以下标来访问数据
at就是访问对象的第pos个位置的数据
back访问最后一个,front是访问第一个数据

	string s1("abcdefg");
	cout << s1[5] << endl;
	cout << s1.at(5) << endl;
	cout << s1.back() << endl;
	cout << s1.front() << endl;

在这里插入图片描述
注意:如果是const类型对象返回值是不能修改的。每个功能都重载了一个const类型
在这里插入图片描述

5.修改

在这里插入图片描述

1.operator+=

在这里插入图片描述
直接可以理解为在string类的后面插入数据

// += 的对象可以是  字符串,string类,字符
	string s1("abcdefg");
	string s2("xxx");
	s1 += s2;
	s1 += "yyy";
	s1 += 'z';

在这里插入图片描述

2.append

在这里插入图片描述
在string类后插入数据,虽然参数比较多,但是函数的形式与之前的构造函数那里意思大致相同

	string s1("abcdefg");
	string s2("xxx");
	string s3("yyy");
	s1.append(s2);
	cout << s1 << endl;

	s1.append(s3,1,2);
	cout << s1 << endl;

	s1.append("zzz");
	cout << s1 << endl;

	const char* str = "qqqqqqqqqqqq";
	s1.append(str, 5);
	cout << s1 << endl;

	s1.append(9, 'r');
	cout << s1 << endl;

在这里插入图片描述

3.push_back

在string类后插入一个字符

	string s1("abcdefg");
	s1.push_back('s');
	cout << s1 << endl;

在这里插入图片描述

4.assign

在这里插入图片描述
功能还是与之前类似,推荐大家亲自动手实现一遍这些功能,这里的参数一眼就可以看的懂
用一个新的字符串覆盖掉这个字符串。功能类似之前的strcpy。

	string s1("abcdefg");
	cout << s1 << endl;

	string s2("xxx");
	s1.assign(s2);
	cout << s1 << endl;

	s1.assign("yyyy");
	cout << s1 << endl;

	s1.assign("123456789",5);
	cout << s1 << endl;

	s1.assign(5, 'c');
	cout << s1 << endl;

在这里插入图片描述

5.insert

在这里插入图片描述
在string类中插入数据

	string s1("abcdefg");
	string s2(" xxx ");
	cout << s1 << endl << endl;

	//在s1的第一个位置插入s2
	s1.insert(1, s2);
	cout << s1 << endl;

	//在s1的第pos个位置插入,s2的第pos后的len给字符
	//string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);
	s1.insert(1, s2, 3, 1);
	cout << s1 << endl << endl;

	//在第pos个位置插入字符串
	s1.insert(0, "sss");
	cout << s1 << endl << endl;

	//在pos位置插入n个字符c
	s1.insert(0, 2, '1');
	cout << s1 << endl << endl;
	//迭代器位置插入n个字符c
	s1.insert(s1.begin(), 2, '2');
	cout << s1 << endl << endl;

	//迭代器位置插入字符c
	s1.insert(s1.begin(), 'z');
	cout << s1 << endl << endl;

在这里插入图片描述

6.erase

删除字符串中的一部分
在这里插入图片描述
可以看到erase函数是有缺省值的如果什么都不传的话就会把字符串清空

//清空字符串
	string s1("abcdefg");
	s1.erase();
	cout << s1.size() << endl;
	cout << s1 << endl;

	//从第三个位置开始删除两个字符
	string s2("abcdefg");
	s2.erase(3,2);
	cout << s2.size() << endl;
	cout << s2 << endl;

	//删除第三个字符之后的字符
	string s3("abcdefg");
	s3.erase(3);
	cout << s3.size() << endl;
	cout << s3 << endl;

在这里插入图片描述

7.replace

在这里插入图片描述
用新内容替换字符串中从字符pos开始并跨越len字符的部分(或字符串中介于[i1,i2)之间的部分)

先讲第一个函数,后面的大致与这个都相同

	string s1("abcdefg");
	cout << s1 << endl;
	string s2("xxxxx");
	string s3("y");
	//s1的pos个位置向后len个长度改为s2
	//如果replace的第二个参数,小于s2的长度则把s2全部拷贝过去
	s1.replace(3, 2, s2);
	cout << s1 << endl;

	//如果replace的第二个参数长度,大于s2
	//那就从pos位置向后数的len给长度替换为s3,不会拷贝s2的 '\0'
	s1.replace(3, 3, s3);
	cout << s1 << endl;

在这里插入图片描述
在这里插入图片描述
迭代器版本:

string& replace (iterator i1, iterator i2, const string& str);
意思为将某个区间替换

	string s1("abcdefg");
	cout << s1 << endl;
	string s2("xxx");
	string::iterator it1 = s1.begin();
	it1 += 3;
	string::iterator it2 = s1.end();
	// 用s2替换掉s1中【it1,it2】的位置
	s1.replace(it1, it2, s2);
	cout << s1 << endl;

在这里插入图片描述
在这里插入图片描述

8.swap

在这里插入图片描述
与另一个string类交换

	string s1("abcdefg");
	string s2("xxxxxxx");
	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;

在这里插入图片描述

9.pop_back

在这里插入图片描述
尾删,每次删除一个字符

strint s1("abcdefg");
cout << s1 << endl;
s1.pop_vack();
cout << s1 << endl;
s1.pop_vack();
cout << s1 << endl;

在这里插入图片描述

6.String operations

在这里插入图片描述

1.c_str,data,copy

	
	string s1("abcdcdcd");
	//获取等价的s1字符串
	const char* str = s1.c_str();
	cout << str << endl;
	//输出s1中的数据
	cout << s1.data() << endl;

	//size_t copy (char* s, size_t len, size_t pos = 0) const;
	//向s中拷贝 len 个字符,从 string类的第pos个位置开始
	char s[10] = "aaaaaa";
	s1.copy(s, 3, 2);
	cout << s1 << endl;
	cout << s << endl;

函数易懂看输出结果就可以知道它的作用了

在这里插入图片描述

2.find系列

find与rfind

	string s1("abcdcd");
	string s2("cd");
	//size_t find(const string& str, size_t pos = 0) const;
	//不传参数
	cout << s1.find(s2) << endl;
	//传递参数
	cout << s1.find(s2, 3) << endl;

	//size_t rfind(const string& str, size_t pos = npos) const;
	//返回最后一次出现的位置,这个函数是从最后一个位置开始查找
	cout << s1.rfind(s2) << endl;
	//传递参数
	cout << s1.rfind(s2,0) << endl;

在这里插入图片描述

find_first_of 与 find_last_of

find_first_of

	string s1("i like you");
	string s2("aeiou");
	
	//在string类中找给定string类中任意一个字符出现的第一个字符
	// 即 s2 中的任意一个字符在 s1 中第一次出现的位置
	cout << s1.find_first_of(s2) << endl;
	
	//也可以指定从 s1 的第pos给位置开始找
	cout << s1.find_first_of(s2, 1) << endl;

在这里插入图片描述

find_last_of
在字符串中搜索与参数中指定的任何字符匹配的最后一个字符。

find_first_not_of 与 find_last_not_of

	string s1("i like you");
	string s2("aeiou");

	//在字符串中搜索第一个与参数中指定的任何字符不匹配的字符。
	cout << s1.find_first_not_of(s2) << endl;

	//在字符串中搜索最后一个与参数中指定的任何字符不匹配的字符。
	cout << s1.find_last_not_of(s2) << endl;

在这里插入图片描述

3.strsub

	string s1("i like you");
	string s2;
	//string substr(size_t pos = 0, size_t len = npos) const;
	//返回一个新构造的字符串对象,其值初始化为此对象的子字符串的副本。
	s2 = s1.substr(2,7);
	cout << s1 << endl;
	cout << s2 << endl;

在这里插入图片描述

4.compare

它的用法与C语言中的字符串比较函数完全一样
int compare (const string& str) const;
比较方法:从第一个字符按ascll码向后比较
大于返回 大于0的数
小于返回小于0的数
等于返回 0

;