C++之string类的使用

C++之string类的使用

  • 1.为什么要学string类
  • 2.标准库中的string类
  • 3.string类的接口的使用
    • 3.1默认成员函数
    • 3.2容量操作
    • 3.3访问操作
    • 3.4遍历操作
    • 3.5修改操作
    • 3.6字符串操作
    • 3.7非成员函数

1.为什么要学string类

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

因此C++标准库提供了字符串类模板,为我们提供了各种功能的接口,而不在关心底层是如何实现的,方便我们去使用。

在学习一个模板的时候,我们需要了解这个模板提供了哪些接口,接口实现了什么功能,返回值等等,这里提供C++标准库,里面有各种模板的详细介绍。

2.标准库中的string类

C++之string类的使用_第1张图片
basic_string是一个标准库提供的字符串类模板,charT是模板参数,表示的是字符类型,字符串由这种类型的一系列字符组成。后面的参数暂时不用管,后面再说。

C++之string类的使用_第2张图片
这个类模板可以实例化上面4种类。

可能会有这样的疑问,字符串里面包含的都是普通字符,为什么要实例化4种类呢?

其原因是因为字符编码的问题。

补充知识

1.我们在C语言所接触最多的是ASCLL,包含了大小写字母,数字,标点符号等等…这套编码是由美国发明的,是符合老美文字习惯。但是为了将计算机推展到全世界,还需要包括其他国家文字。因此有了统一码(unicode)也叫万国码。

2.unicode有UTF-8、UTF-16、UTF-32三种将数字转换到程序数据的编码方案。一个字大小分别占1个字节,2个字节,4个字节。

3.我们使用最多是UTF-8,这种编码方案兼容ASCLL,还省空间。

C++之string类的使用_第3张图片

以后根据字符编码不同,可以选择对应的实例化的类。

简单认识string类的构成

template<class T>
class basic_string
{
public:
	//各种成员函数
private:
	T* _str;
	size_t _size;
	size_t _capacity
};

typedef basic_string<char> string;

int main()
{
	//这两种是等价的
	basic_string<char> s;
	string s;
}

字符串类其实本质就是动态增长的数组,学过数据结构的数组,这里更容易理解。

使用string必须包含头文件

#include

3.string类的接口的使用

string类每一种接口都有很多函数重载,下面主要讲述的是一些常用的需要重点掌握的,不需要看文档就会用的,其他没有讲述的如果需要用,在查文档。

3.1默认成员函数

C++之string类的使用_第4张图片
默认成员函数包括:构造函数(包含拷贝构造函数),析构函数,赋值运算符重载函数

构造函数

在这里插入图片描述
拷贝构造函数是构造函数的重载,因此构造函数包含里包含拷贝构造函数。

C++之string类的使用_第5张图片

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

C++之string类的使用_第6张图片

赋值运算符重载函数

在这里插入图片描述
C++之string类的使用_第7张图片
C++之string类的使用_第8张图片

3.2容量操作

C++之string类的使用_第9张图片

函数名称 功能说明
size(重点) 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty (重点) 检测字符串释放为空串,是返回true,否则返回false
clear (重点) 清空有效字符
reserve (重点) 为字符串预留空间
resize (重点) 将有效字符的个数该成n个,多出的空间用字符c填充

C++之string类的使用_第10张图片

size和length都返回字符串有效字符长度,不包括’\0’。

这里可能会有疑问,一样功能的实现两个函数?

1.最开始求字符串有效字符长度只有length,但是有了STL(标准模板库)之后,涉及的模板多了起来,如求二叉树结点个数,链表长度,就不是能用length能表达清楚的了,所以有了size。
2.string为了符合STL(标准模板库),也有了size,在后面我们经常使用的是size。

C++之string类的使用_第11张图片

当string类存放字符空间是动态开辟的,空间不够会扩容。

	//插入1000个字符,看是否扩容
	string s;
	size_t capacity = s.capacity();
	cout << "capacity:" << capacity << endl;
	for (int i = 0; i < 1000; ++i)
	{
		s.push_back('x');
		if (capacity != s.capacity())
		{
			capacity = s.capacity();
			cout << "change capacith:" << capacity << endl;
		}
	}

C++之string类的使用_第12张图片
不同编译器扩容是不一样的。下面看看在Linux情况下,同一段代码扩容情况。

C++之string类的使用_第13张图片
C++之string类的使用_第14张图片
可以看见在Liunx下,同样代码,每次申请空间都是2倍。

我们知道频繁扩容是有代价的。如果我们预先知道开辟多大空间,就可以减少扩容,提高效率。

reserve为字符串预留空间。

C++之string类的使用_第15张图片

empty判断字符串是为空。

C++之string类的使用_第16张图片
clear清楚有效字符,清除之后是否缩容,看string类是如何规定。

C++之string类的使用_第17张图片

resize,将有效字符的个数改成n个,多出的空间用字符c填充
resize有三种情况:
1.n
C++之string类的使用_第18张图片

删除数据

2.size
C++之string类的使用_第19张图片

插入数据,如果没有指定用’\0’填充。

3.n>capacity
C++之string类的使用_第20张图片

扩容+插入数据

3.3访问操作

C++之string类的使用_第21张图片

函数名称 功能说明
operator[] (重点) 返回pos位置的字符,const string类对象调用

C++之string类的使用_第22张图片

operator[]是常用的访问操作,不仅可以访问,还可以修改。

C++之string类的使用_第23张图片

3.4遍历操作

void test_string4()
{
	string s("hello world");
	//遍历
	//1.普通遍历
	for (size_t i = 0; i < s.size(); ++i)
	{
		//字符+1
		s[i] += 1;
		cout << s[i] << " ";
	}
	cout << endl;

	//2.范围for遍历
	for (auto& ch : s)
	{
		//字符-1
		ch -= 1;
		cout << ch << " ";
	}
	cout << endl;

	//3.迭代器iterator
}

C++之string类的使用_第24张图片

迭代器:是一种通用的访问方式。

iterators行为上像指针一样的类型
注意不同迭代器是不一样的。

	//3.迭代器iterator
	//正向迭代
	string::iterator it1 = s.begin();
	while (it1 != s.end())
	{
		*it1 += 1;
		++it1;
	}
	it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

C++之string类的使用_第25张图片
返回字符串第一个数据位置

在这里插入图片描述
返回字符串最后一个有效数据的下一个位置。

	//反向迭代
	string::reverse_iterator it2 = s.rbegin();
	while (it2 != s.rend())
	{
		cout << *it2 << " ";
		++it2;
	}
	cout << endl;

C++之string类的使用_第26张图片

C++之string类的使用_第27张图片

rebegin返回有效字符最后一个位置

C++之string类的使用_第28张图片

rend返回有效字符第一个位置

	//const正向迭代
	//只能遍历,不支持修改
	string::const_iterator it3 = s.begin();
	while (it3 != s.end())
	{
		cout << *it3 << " ";
		++it3;
	}
	cout << endl;

	//const反向迭代
	//只能遍历,不支持修改
	//string::const_reverse_iterator it4 = s.rbegin();
	//auto 根据右边推测左边的类型
	auto it4 = s.rbegin();
	while (it4 != s.rend())
	{
		cout << *it4 << " ";
		++it4;
	}
	cout << endl;

我们看见有的接口实现了两种类型,一个加const,一个没加const。
如果我们自己实现一个类也需要考虑要不要加上实现加const版本的函数。
C++之string类的使用_第29张图片
总结:

1.只读功能函数,只提供const版本即可
2.只写功能函数,只提供非const版本即可
3.读写功能函数,需提供const+非const版本

3.5修改操作

C++之string类的使用_第30张图片

函数名称 功能说明
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= (重点) 在字符串后追加字符串str
insert 插入字符串
erase 删除字符串中的字符
assign 为字符串指定一个新值,替换其当前内容。
swap 交换字符串值

push_back
C++之string类的使用_第31张图片

append 和构造函数的重载函数一样,但是常用的是第一个和第三个

C++之string类的使用_第32张图片
C++之string类的使用_第33张图片

operator+=是我们需要重点掌握的

C++之string类的使用_第34张图片
C++之string类的使用_第35张图片

insert 插入字符串
插入意味着挪动数据,所以string很少使用

C++之string类的使用_第36张图片
C++之string类的使用_第37张图片
剩下的可以自行了解文档。

erase删除字符串中的字符
也是要挪动属性,很少使用。

C++之string类的使用_第38张图片

默认开始位置是0,默认长度是npos

C++之string类的使用_第39张图片

size_t是无符号整型 ,-1会整型提升无符号整型,因此-1就变成了4294967295。

C++之string类的使用_第40张图片

assign和replace都是替代原有的字符串,但是assign是清理掉原数组之后在赋值,而replace不清理原数组,直接替代。

C++之string类的使用_第41张图片

C++之string类的使用_第42张图片

C++之string类的使用_第43张图片
C++之string类的使用_第44张图片

swap交换字符串的值
C++之string类的使用_第45张图片

C++之string类的使用_第46张图片

3.6字符串操作

C++之string类的使用_第47张图片

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

c_str返回c格式字符串。

C++之string类的使用_第48张图片

注意返回值是 const类型。

C++之string类的使用_第49张图片

find,正向在字符串中查找内容

C++之string类的使用_第50张图片
找到返回第一个匹配的第一个字符的位置。找不到返回string::npos

C++之string类的使用_第51张图片

rfind,反向在字符串中查找内容。

C++之string类的使用_第52张图片

C++之string类的使用_第53张图片

**find_first_of,查找字符串中的字符,该函数和find不一样,这个函数会搜索参数中指定的任何字符匹配的第一个字符。。当指定位置时,搜索仅包括位置位置处或位置之后的字符,忽略位置之前可能出现的任何字符。**当作了解即可,用的很少。

C++之string类的使用_第54张图片

搜索成功返回匹配字符的位置,不成功返回npos

C++之string类的使用_第55张图片
C++之string类的使用_第56张图片

substr生成子字符串
返回一个新构造的字符串对象

C++之string类的使用_第57张图片
C++之string类的使用_第58张图片

3.7非成员函数

C++之string类的使用_第59张图片

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

operator>>从流中提取字符串

C++之string类的使用_第60张图片
operator<<将字符串插入流
C++之string类的使用_第61张图片

C++之string类的使用_第62张图片
为什么输的是hello world,结果只打印处理hello呢?

cin和scanf都是输入,cin标准化输入,scanf格式化输入。
cin取数据时会忽略空格和回车继续输入。
scanf取数据时遇到回车、空格就会停止。
为了使cin和scanf一样,库里面实现的operator<<就针对做了特殊处理。

如果就想拿到整个字符串,使用getline函数将行从流转换为字符串
C++之string类的使用_第63张图片

C++之string类的使用_第64张图片

relational operators是字符串大小比较的接口
C++之string类的使用_第65张图片
C++之string类的使用_第66张图片

string类接口还有很多,这里只是例举了一些比较重要的,都标上了重点。需要不看文档就知道怎么。剩下的内容大家在下面在多多练习。好了本篇string类的使用到这里就结束喽。
下篇string类的模拟实现.

喜欢的小伙伴,点赞,评论,加收藏!感谢支持!

你可能感兴趣的:(C++从入门到精通,c++,java,jvm)