C++入门 string类(第二章):string类对象的容量操作,string类对象访问元素,string类对象的字符串操作(查找)

🚀1. string类对象的容量操作

在这里插入图片描述

⚡️1.1 size

在这里插入图片描述
size返回string类对象的_size属性,也就是string的长度。注意:size不包含\0

int main()
{
	string s1("Hello world");
	cout << s1.size() << endl;
}

在这里插入图片描述
也可以用length,与size功能一样
在这里插入图片描述
我们更常用size,length是历史遗留的函数,为了与后面的容器统一所以用size

⚡️1.2 capacity

在这里插入图片描述
capacity返回string类对象的_capacity属性,也就是对象的现有容量。这个属性与size不同,size是现有成员的个数,capacity是现有容量大小,当size = capacity时,对象会扩容。这是为了避免每次添加字符时都要重新分配内存,提高性能。

int main()
{
	string s1("Hello world");
	cout << s1.capacity() << endl;
}

在这里插入图片描述
capacity会比实际的空间要小一个字节,有多一个预留给\0的,这里现有容量实际上是16字节,

题外话:在vs2022有点需要注意,对于长度不大的string类对象,其字符串是建在栈上的,长度大的string类对象是建在堆上的。

int main()
{
	string s1("Hello world");
	string s2("Hello world!!!!!!!!!!!!!!!!");
}

在这里插入图片描述
可以看到s1的"Hello world"是在_Buf上的,_Buf其实在上的。

在这里插入图片描述

而s2的长度过长,是存在_Ptr上的,_Ptr是在上的。

这其中的缘由是因为,vs2022一开始是在栈上存字符串,而扩容的操作实际上的在堆上开空间,再把字符串拷贝进去的,这是vs2022对string类优化的一种方式。

⚡️1.3 max_size

在这里插入图片描述
这个函数一般没什么用,从字面意思上是string开辟的最大成员个数,但实际上string都开不到这么大的空间

⚡️1.4 resize

在这里插入图片描述
resize用于将字符串的大小调整为n个字符的长度,改变string对象中的_size属性,当n>_capacity,_capacity也会扩容

用法:

  1. 当写入第二个参数char c还可以初始化调整后的内容,原先的字符内容会保留,多的size会被填充为 char c
int main()
{
	string s1("Hello world");
	s1.resize(100,'!');
	cout << s1 << endl;//输出Hello
}

在这里插入图片描述
2. 删除内容,resizen < 原先的size,会删除多的内容

int main()
{
	string s1("Hello world");
	s1.resize(5);
	cout << s1 << endl;//输出Hello
}

⚡️1.5 reserve

reserve改变string对象中的_capacity属性,使用场景:当知道string大概有多长时,可以使用reserve先扩大,就可以减少频繁开空间带来的消耗,提高效率。

int main()
{
	string s1("Hello world");
	s1.reserve(20);
	s1 += "!!!!!!!!";
	cout << s1 << endl;
}

注意:不要轻易缩容!!,缩容的本质的时间换空间,效率很低

⚡️1.6 clear

在这里插入图片描述
clear用于清空string的所有内容,

int main()
{
	string s1("Hello world");
	s1.clear();
	cout << s1 << endl;
}

⚡️1.7 empty

在这里插入图片描述
empty判断string是否为空,空则true,非空则false。

int main()
{
	string s1("Hello world");
	string s2;
	
	cout << s1.empty() << endl;//false
	cout << s2.empty() << endl;//ture
}

🚀2. string类对象访问元素

在这里插入图片描述
operator[]不必多说,就是像数组一样访问string里的元素。

⚡️2.1 at

在这里插入图片描述
at函数与[ ]的作用相同,但[ ]访问越界时,是暴力的直接报错,而at是报异常

int main()
{
	string test("hello!");
	try
	{
		test.at(10);//访问越界
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
}

在这里插入图片描述

⚡️2.2 back 与 front

在这里插入图片描述

back 与 front分别返回string的尾字符和头字符,这两个函数返回的是引用,是字符本身。

int main()
{
	string test("hello!");
	cout << test.front() << " " << test.back()<<endl;
	test.front() = 'H';
	test.back() = '?';
	cout << test.front() << " " << test.back() << endl;
}

在这里插入图片描述

🚀3. string类对象的字符串操作(查找)

在这里插入图片描述

⚡️3.1 c_str

在这里插入图片描述
c_str会返回string类对象的字符数组。使用场景:因为c语言没有string,只有字符数组构成的字符串,c++在使用c语言的函数时,就可以调用c_str传参。

#include <iostream>
using namespace std;
int main()
{
	string file("test.cpp");
	//fopen是c语言库的函数,第一个参数类型为 char*
	FILE* fout = fopen(file.c_str(), "r");
	char ch = fgetc(fout);
	while (ch != EOF)
	{
		cout << ch;
		ch = fgetc(fout);
	}
}

⚡️3.2 find 与 rfind

在这里插入图片描述
find 会从string类对象的第一个字符开始I(如果有pos参数,就从pos参数开始),正着找第一个相同的 字符串/字符,并返回其下标如果找不到会返回 string::npos

注意string::npos 字面意表示字符最大长度,数值等于 -1

int main()
{
	string file("test.cpp.zip");
	// 1.find(const string & str, size_t pos = 0) const;
	int test1=  file.find("cpp");
	// 2 find(char c, size_t pos = 0) const;
	int test2 = file.find('.',5);
	cout << "test1 = " << test1<<"  " << "test2 = " << test2;
	// 3 找不到
	int test3 = file.find('.',5);
	cout << "test1 = " << test1<<"  " << "test2 = " << test2;
}

运行结果:
在这里插入图片描述


rfind
在这里插入图片描述
rfind find 语法相同,但rfind 是倒着找。

⚡️3.3 substr

在这里插入图片描述

string substr (size_t pos = 0, size_t len = npos) const;

substr截断从pos下标开始,往后的len个字符,并返回这个截断的字符串(string类型)

substr常与 rfind find 配合使用,用于截断文件名的后缀和id。

int main()
{
	
		string file("string.cpp.zip");
		size_t pos_head = file.find('.');
		size_t pos_end = file.rfind('.');
		string suffix_1 = file.substr(0,0+ pos_head);
		string suffix_2 = file.substr(pos_end+1);

		cout << suffix_1 << endl;
		cout << suffix_2 << endl;
}

运行结果:
在这里插入图片描述

⚡️3.4 find_first_of 与 find_last_of

在这里插入图片描述
第一个参数为字符串str,第二个位置为开始查找的下标pos, find_first_of会从pos开始,正序遍历字符与str内的字符相比较,如果这个字符 等于 str内的字符,返回其下标

int main()
{
	string file("string.cpp.zip");
	int pos1 = file.find_first_of("crazy");//下标2的r符合

	int pos2 = file.find_first_of("tiger");//下标1的t符合
	
	cout << pos1 << pos2 << endl;
}

运行结果:
在这里插入图片描述

find_last_of
在这里插入图片描述
find_last_offind_first_of语法相同,但find_last_of 是从pos位置倒着找。

⚡️3.5 find_first_not_of 与 find_last_not_of

在这里插入图片描述
find_first_of很像,find_first_not_of会从pos开始,正序遍历字符与str内的字符相比较,如果这个字符 不等于 str内的字符,返回其下标。

int main()
{
	string file("string.cpp.zip");
	int pos1 = file.find_first_not_of("crazy");//下标0的r符合

	int pos2 = file.find_first_not_of("singer");//下标1的t符合
	
	cout << pos1 <<" " << pos2 << endl;
}

运行结果:
在这里插入图片描述



感谢你能看到这里!!

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值