C++STL标准模板库——String类


在这里插入图片描述

一、STL简介

1.1 什么是STL?

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分 ,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架

1.2 STL的六大组件

在这里插入图片描述

二、string类

2.1 为什么学习string?

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问 。

在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数 。

2.2 标准库中的string类

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
  4. 不能操作多字节或者变长字符的序列。

在使用string类时,必须包含#include头文件以及using namespace std;

2.3 string类对象的常见构造

构造函数名称功能说明
string()(重点)构造空的string类对象,即空字符串
string(const char* s) (重点)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string&s) (重点)拷贝构造函数

在这里插入图片描述

2.4 string类对象的容量操作

函数名称功能说明
size(重点)构造空的string类对象,即空字符串
length用C-string来构造string类对象
capacitystring类对象中包含n个字符c
empty(重点)拷贝构造函数
clear(重点)清空有效字符
reserve(重点)为字符串预留空间
resize(重点)将有效字符的个数改成n个,多出的空间用字符c填充
void TestString1()
{
	string s("hello");
	cout << s.size() << endl;	//返回字符串中的有效字符,不包含'\0'
	cout << s.length() << endl;	//等同于size,但是通常不用length求有效字符
	cout << s.capacity() << endl;	//返回空间总大小,同样不包含'\0'
	cout << s << endl;	//string类对象支持cin输入和cout打印

	// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
	s.clear();
	cout << s.size() << endl;	
	cout << s.capacity() << endl;

	// 将s中有效字符个数增加到10个,多出位置用'a'进行填充
	// “aaaaaaaaaa”
	s.resize(10, 'a');
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	// 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
	// "aaaaaaaaaa\0\0\0\0\0"
	// 注意此时s中有效字符个数已经增加到15个
	s.resize(15);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	// 将s中有效字符个数缩小到5个
	s.resize(5);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

}

在这里插入图片描述

假设不指定空间大小则每次都会扩容,带来计算开销

// 利用reserve提高插入数据的效率,避免增容带来的开销
void TestPushBack()
{
	string s;
	size_t sz = s.capacity();
	cout << s.capacity() << endl;
	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';
		}
	}
}

在这里插入图片描述

reserve的应用场景是为了解决string的增容缺陷,假设我们已经知道要开辟多大空间时,可以直接指定空间大小,避免增容带来的开销

// 利用reserve提高插入数据的效率,避免增容带来的开销
void TestPushBackReserve()
{
	string s;
	s.reserve(100);
	size_t sz = s.capacity();
	cout << s.capacity() << endl;
	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';
		}
	}
}

在这里插入图片描述

使用reserve注意以下问题

void TestString3()
{
	string s;
	// 测试reserve是否会改变string中有效元素个数
	s.reserve(100);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	// 测试reserve参数小于string的底层空间大小时,是否会将空间缩小
	s.reserve(50);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

在这里插入图片描述

总结

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

  2. clear()只是将string中有效字符清空,不改变底层空间大小。

  3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字
    符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的
    元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大
    小,如果是将元素个数减少,底层空间总大小不变。

  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于
    string的底层空间总大小时,reserver不会改变容量大小。

  5. reserve和resize的区别是,reserve只增容不改变有效元素个数,resize即改变容量空间又对容量空间初始化。

2.5 string类对象的访问及遍历操作

函数名称功能说明
operator[]返回pos位置的字符,const string类对象调用
begin+ endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
范围forC++11支持更简洁的范围for的新遍历方式

<1> operator[]

void TestStringOperator1()
{
	string s1("hello world");
	cout << s1 << endl;
	s1[0] = 'H';
	cout << s1 << endl;

	const string s2("hello c++");
	// s2[0] = 'h'; 代码编译失败,因为const类型对象不能修改
}

在这里插入图片描述

<2> 迭代器

对于迭代器,我们暂时可以将其看成指针

//迭代器
void TestStringIterator()
{
	string s("hello world");
	//三种遍历方式:
	//以下三种方式除遍历string外还可修改string中的字符
	//第一种使用较多
	//1.for+operator[]
	cout << "for+operator[]" << endl;
	for (size_t i = 0; i < s.size() - 1; ++i)
	{
		cout << s[i] << " "<< endl;
	}
	//2.正向迭代器
	cout << "2.正向迭代器" << endl;
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << endl;
		++it;
	}
	//2.反向迭代器
	cout << "2.反向迭代器"<<endl;
	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit << endl;
		++rit;
	}
	//3.范围for
	cout << "3.范围for" << endl;
	for (auto ch : s)
	{
		cout << ch << endl;
	}

在这里插入图片描述

2.6 string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+= (重点)在字符串后追加字符串str
c_str(重点)返回C格式字符串
find + npos(重点)从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

<1> 在字符串后尾插字符

在这里插入图片描述

<2> 字符串查找

//找文件尾
void TestStringFind()
{
	string s = "hello world";
	s.push_back('!');	//字符串后尾插字符
	cout << s << endl;
	s.append("HELLO");	//字符串后追加字符串
	cout << s << endl;
	s += 'W';			//+=追加字符
	cout << s << endl;
	s += "ORLD";		//+=追加字符串
	cout << s << endl;
	s += s;				//追加string对象
	cout << s << endl;


	string file1("string.cpp");
	string file4("string.c.tar.zip");

	//substr第二个参数可以不写,从前往后找
	size_t pos = file1.find('.');
	if (pos != string::npos)
	{
		cout << file1.substr(pos, file1.size() - pos) << endl;
	}

	//rfind从后往前找
	size_t pos4 = file4.rfind('.');
	if (pos4 != string::npos)
	{
		cout << file4.substr(pos4) << endl;
	}

	//分割域名
	string url = "http://cplusplus.com/reference/string/string/find/";
	cout << url << endl;
	size_t pos5 = url.find(':');	//第一个冒号分割http
	if (pos5 != string::npos)
	{
		cout << url.substr(0, pos5) << endl;
	}

	size_t pos6 = url.find('/', pos5 + 3);	//pos5+3:c  pos6:/
	if (pos6 != string::npos)				//分割网址cplusplus.com
	{
		cout << url.substr(pos5 + 3, pos6 - (pos5 + 3)) << endl;
	}

	cout << url.substr(pos6 + 1, string::npos) << endl;
	//删除http
	string copy = url;
	cout << copy.erase(0, pos5 + 3) << endl;

}

在这里插入图片描述

在这里插入图片描述

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般
    情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

2.7 string类的非成员函数

函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>> (重点)输入运算符重载
operator<< (重点)输出运算符重载
getline (重点)获取一行字符串
relational operators (重点)大小比较

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C++ 标准模板STL)是一个强大的工具,为程序员提供了许多可以直接使用的容器、算法和迭代器。《C++ 标准模板编程实战》这本书集中讲解了 STL 的使用方法和实战技巧,旨在帮助读者开发出高效且易于维护的 C++ 程序。 这本书共分为四个部分。第一部分介绍了 STL 的基础知识,主要包括容器、迭代器、算法、函数对象等内容。第二部分重点讲解了序列容器和关联容器,以及它们常见的应用。第三部分主要是算法,详细介绍了 STL 中常用的算法,并且通过实例演示了其使用方法。第四部分主要是 STL 的高级应用,如智能指针、异常处理、多线程等。 此外,这本书还提供了大量的实战案例,这些案例既包括独立的小应用程序,也包括较为完整的项目代码。通过这些案例,读者可以深入了解 STL 的使用和设计思路,并掌握一些实用的编程技巧。 总的来说,这本《C++ 标准模板编程实战》是一本非常实用的书籍,不仅适合初学者入门,也适合有一定经验的开发者进一步提高自己的编程技能。建议读者在学习这本书时,可以边读边动手实践,更好地理解和掌握其中的内容。 ### 回答2: c++标准模板编程实战是一本非常经典、详实的c++ STL实战教材,主要讲解了STL的各种容器、算法和迭代器的常用操作和实现原理,并且通过大量的实例演示了STL在真实项目中的实际应用。 本书总共分为10个章节,前两章是介绍STL的基础知识和核心组件,包括迭代器、容器、算法等;第三章是介绍序列容器,主要包括vector、list、deque、stack、queue、heap、priority_queue和bitset等;第四章是介绍关联容器,主要包括set、multiset、map、multimap等;第五章是介绍迭代器,包括迭代器分,迭代器实现方式和应用场景等;第六章是介绍函数对象,包括函数对象的定义、STL内置函数对象、自定义函数对象和函数对象适配器等;第七章是介绍算法基础,包括常用算法和自定义算法的实现;第八章是介绍字符串,在字符串操作方面,STL提供了string和wstring,以及一些与之相关的算法;第九章是介绍STL的高级用法,包括元编程、策略模式、继承体系、嵌套和allocator等;第十章是介绍STL和相关技术的未来发展趋势和发展方向。 总的来说,c++标准模板编程实战是一本非常好的STL实战教材,既可以作为初学者入门的指南,也可以作为中高级程序员巩固和深入学习STL的参考书。无论是学习STL的基础知识、习惯性使用STL容器和算法,还是在项目中灵活高效地应用STL,都会受益匪浅。 ### 回答3: c标准模板STL)是一组C++模板和函数的集合,可以让程序员使用一些高效的算法和数据结构,从而降低了开发者的工作量,提高了C++程序的效率和可维护性。 《C++标准模板编程实战》是一本介绍STL的经典教材,全书共分为25个章节,内容涉及到STL的迭代器、算法、容器、函数对象、适配器等方面。可谓是STL入门的重要读物。 该书的编写思路以工程实践为导向,讲解一些常用的数据结构和算法的实现过程,并给出了一些标准中经典的函数的代码实现。例如,生成随机数的代码、字符串排序的代码、实现二叉堆的代码等等。这些代码可以帮助开发者更好地理解STL中的模板和函数的实现原理和效率。 此外,该书对STL的算法进行了详细介绍,包括容器、迭代器、函数对象等方面的应用。为了方便程序员,书中还提供了一些实用的STL程序的代码,例如STL的多个容器和关联式容器,还有STL中提供的适配器等。 总之,《C++标准模板编程实战》是学习STL的必备参考书,不仅深入浅出地讲解了STL的实现原理和应用,更是教会了我们如何将STL运用到工程中,将编程变得更加高效和简单。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值