C++初阶——string的使用(下)

C++初阶——string的使用(下)

一、string类对象的容量操作

对于string的容量操作,我们可以通过顺序表来理解,顺序表是通过动态数组来实现的,在数据结构专栏的第一篇就是顺序表的详细讲解,链接如下:link
我们先来看一下顺序表的结构体:
示例1
这里是一个整型数组,通过类型重命名typedef可以将其调整为字符型数组,对字符串进行操作。当然,之前的顺序表是基于C语言实现的,我们这里的string就会使用类(class)来进行模拟实现,下期内容会进行详细讲解。
我们看这里的成员,有一个size,表示目前数组里有几个有效数据;capacity,表示数组目前的容量多大,当sizecapacity相等时,就需要使用动态内存开辟进行扩容
string类中也是如此:

  • size:返回字符串有效字符长度
  • capacity 返回空间总大小
  • length:返回字符串有效字符长度
  • empty:检测字符串释放为空串,是返回true,否则返回false
  • clear:清空有效字符
  • reserve:为字符串预留空间
  • resize:将有效字符的个数该成n个,多出的空间用字符c填充

我们来看这样一段代码:
示例2
这里不仅对几种容量相关的函数进行了测试,还进一步的探究了扩容的机制,结果如下:
示例3
不同环境下扩容的机制不同,这里是VS2022的扩容机制。

1.size

示例4

2.capacity

示例5

3.length

示例6
size()length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()

4.max_size

示例7
(这个函数没有什么特别大的作用)

5.clear

示例8
需要注意的是,clear只是清除了有效数据,并没有把容量(capacity)清零。

6.reserve

示例9
使用说明:
示例10

  • reserve(size_t res_arg=0);:为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间(就是在实例化的过程中就有的内置空间)总大小时,reserve不会改变容量大小。
  • 运行结果如图:
    示例11

7.resize

我们还是以代码为例:
示例12
运行结果如图:
示例13
resize(size_t n)resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变,我们来看一下使用说明:
示例14

8.empty

empty比较简单,需要注意的是这里判断依据不是容量 (capacity),而是有效数据的长度(size、length)是否为零,使用说明如下:
示例15

二、string的其他常用操作

1.replace

示例16
replace顾名思义就是一个替换函数,可以根据自己的需要替换字符串中某些位置的值,其重载的函数多种多样,功能很丰富,使用介绍如图所示:
示例17
运行结果如图:
示例18

2.find函数

示例19
find也是一个非常重要的成员函数,用来寻找所需的字符或者字符串,当然也需要提供查找的范围,如果不提供,默认从第一个位置开始寻找,使用介绍如下:
示例20
至于其它的一些find相关的函数,我们也稍作介绍:

  • find_first_of
    示例21
  • find_last_of
    示例22
  • refind
    示例23

三、本期代码资源

//int main()
//{
//	string s1("hello world");
//
//	cout << s1.size() << endl;
//	cout << s1.length() << endl;
//	cout << s1.max_size() << endl;
//	cout << s1.capacity() << endl;
//	
//	size_t old = s1.capacity();
//	for (size_t i = 0; i < 100; i++)
//	{
//		s1 += 'x';
//		if (old != s1.capacity())
//		{
//			cout << "扩容:" << s1.capacity() << endl;
//			old = s1.capacity();
//		}
//	}
//
//	cout << s1.size() << endl;
//	cout << s1.capacity() << endl;
//
//	s1.clear();
//	cout << s1.size() << endl;
//	cout << s1.capacity() << endl;
//
//	return 0;
//}

//void TestPushBackReserve()
//{
//	string s;
//	s.reserve(100);
//	size_t sz = s.capacity();
//	cout << "capacity changed: " << sz << '\n';
//	cout << "making s grow:\n";
//	for (int i = 0; i < 100; ++i)
//	{
//		s.push_back('c');
//		if (sz != s.capacity())
//		{
//			sz = s.capacity();
//			cout << "capacity changed: " << sz << '\n';
//		}
//	}
//	s.clear();
//	cout << "capacity changed: " << sz << '\n';
//	s.reserve(10);
//	sz = s.capacity();
//	cout << "capacity changed: " << sz << '\n';
//}
//
//int main()
//{
//	TestPushBackReserve();
//	return 0;
//}

//int main()
//{
//	string s1("hello world");
//
//	//开空间
//	s1.reserve(100);
//	cout << s1.size() << endl;
//	cout << s1.capacity() << endl;
//
//	//开空间+填值初始化
//	//s1.resize(200);
//	s1.resize(200, 'x');
//	cout << s1.size() << endl;
//	cout << s1.capacity() << endl;
//
//	s1.resize(20);
//	cout << s1.size() << endl;
//	cout << s1.capacity() << endl;
//
//	s1.resize(0);
//	cout << s1.size() << endl;
//	cout << s1.capacity() << endl;
//
//	return 0;
//}

//int main()
//{
//	try {
//		string s1("hello world");
//		s1.at(0) = 'x';
//		cout << s1 << endl;
//		s1.at(15);
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//
//	return 0;
//}

//int main()
//{
//	char str[] = "abcdefg";
//	string s1("hello world");
//	s1.push_back('!');
//	cout << s1 << endl;
//	s1.append(str,3);
//	cout << s1 << endl;
//
//	s1.append("ssssss");
//	cout << s1 << endl;
//	
//	s1.assign("111111111");
//	cout << s1 << endl;
//
//	s1.insert(0, "hello");
//	cout << s1 << endl;
//
//	s1.insert(5, "world");
//	cout << s1 << endl;
//
//	s1.insert(0, 10, 'x');
//	cout << s1 << endl;
//
//	s1.insert(s1.begin()+10, 10, 'y');
//	cout << s1 << endl;
//
//	s1.erase(5, 6);
//	cout << s1 << endl;
//
//	return 0;
//}

//int main()
//{
//	//world替换成 xxxxxxxxxxxxxxxxxxxxxx
//	string s1("hello world hello bit");
//	s1.replace(6, 5, "xxxxxxxxxxxxxxxxxxxxxx");
//	cout << s1 << endl;
//
//	s1.replace(6, 23, "yyyyy");
//	cout << s1 << endl;
//
//	//所有空格替换成20%
//	string s2("hello world hello bit");
//	string s3;
//	for (auto ch : s2)
//	{
//		if (ch != ' ')
//		{
//			s3 += ch;
//		}
//		else
//		{
//			s3 += "20%";
//		}
//	}
//
//	s2 = s3;
//	cout << s2 << endl;
//	cout << s2.c_str() << endl;
//
//	//c的一些接口函数配合
//	string filename = "test.cpp";
//	filename += ".zip";
//
//	//FILE* fout = fopen(filename.c_str(), "r");
//
//	return 0;
//}

//int main()
//{
//	string url = "ftp://www.baidu.com/?tn=65081411_1_oem_dg";
//	// http://www.baidu.com/?tn=65081411_1_oem_dg
//	//string url = "https://legacy.cplusplus.com/reference/string/string/";
//	// 协议  域名  资源名
//	size_t pos1 = url.find("://");
//	string protocol;
//	if (pos1 != string::npos)
//	{
//		protocol = url.substr(0, pos1);
//	}
//	cout << protocol << endl;
//
//	string domain;
//	string uri;
//
//	size_t pos2 = url.find('/', pos1 + 3);
//	if (pos2 != string::npos)
//	{
//		domain = url.substr(pos1 + 3, pos2 - (pos1 + 3));
//		uri = url.substr(pos2 + 1);
//	}
//	cout << domain << endl;
//	cout << uri << endl;
//
//	return 0;
//}

//int main()
//{
//	std::string str("Please, replace the vowels in this sentence by asterisks.");
//	std::size_t found = str.find_first_of("abc");
//	while (found != std::string::npos)
//	{
//		str[found] = '*';
//		found = str.find_first_of("abc", found + 1);
//	}
//
//	std::cout << str << '\n';
//
//	return 0;
//}

本期总结+下期预告

本期内容继续介绍了string类的使用,下期内容将要开始进行string的模拟实现!

感谢大家的关注,我们下期再见!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值