string目录
三、string的类模板(什么?string居然利用了模板??)
[4.1 [ ] + 下标(operator[ ]的重载函数)](#4.1 [ ] + 下标(operator[ ]的重载函数))
五、string的迭代器(迭代器是一个类,封装了指针,模拟了指针的操作)
六、string之capacity(resize,reserve,clear)8
[6.1resize(Resizes the string to a length of n characters)](#6.1resize(Resizes the string to a length of n characters))
6.2reserve预留空间(一般用于扩容)(不会改变size)
[七、string之Element Access(元素访问)](#七、string之Element Access(元素访问))
八、string之modify(+=,append,insert,erase,swap)
[8.5 swap(是一个参数,和平常见到的普通的不一样)](#8.5 swap(是一个参数,和平常见到的普通的不一样))
九、string之operation操作函数(c_str,find,,substr)
9.1c_str(为了使得C++与C语言之间有接口,算是大使馆)

如果你很赶时间,那么就直接看我本标题下的内容即可!!
当然,请看下面的列表,其中包含了C++中`std::string`类的常用成员函数和操作符,以及每个函数和操作符的简要描述和一个示例用法:
- `begin`: 得到指向字符串开头的Iterator
cpp
std::string::iterator it = str.begin();
- `end`: 得到指向字符串结尾的Iterator
cpp
std::string::iterator it_end = str.end();
- `size` (或 `length`): 得到字符串的大小(capacity是返回字符串开辟空间的大小)
cpp
std::string str = "Hello";
std::cout << "Size: " << str.size() << std::endl;
- `empty`: 判断是否为空
cpp
if (str.empty()) {
std::cout << "String is empty." << std::endl;
}
- `operator[]`: 取第n个元素,相当于数组
cpp
char firstChar = str[0];
- `c_str`: 取得C风格的const char* 字符串
cpp
const char* cString = str.c_str();
- `data`: 取得字符串内容地址
cpp
const char* data = str.data();
- `operator+=`: 字符串尾插操作符
cpp
str1 += str2;
- `find`: 查找子串在字符串中的位置
cpp
size_t found = str.find("World");
- `substr`: 得到子串
cpp
std::string sub = str.substr(6, 5);
- `compare`: 比较字符串
cpp
int result = str1.compare(str2);
if (result == 0) {
std::cout << "Strings are equal." << std::endl;
}
- `operator+`: 字符串链接
cpp
std::string result = str1 + str2;
- `operator==`: 判断是否相等
cpp
if (str1 == str2) {
std::cout << "Strings are equal." << std::endl;
}
- `operator!=`: 判断是否不等于
cpp
if (str1 != str2) {
std::cout << "Strings are not equal." << std::endl;
}
- `operator<`: 判断是否小于
cpp
if (str1 < str2) {
std::cout << "str1 is less than str2." << std::endl;
}
- `insert`: 插入字符
cpp
str.insert(3, " inserted");
- `resize`: 重新分配空间
- 描述:`resize` 函数用于更改字符串的大小,可以增加或减小字符串的长度。如果新的大小大于当前大小,新元素将被默认初始化。(三种情况)
cpp
std::string str = "Hello";
str.resize(8); // 增加字符串大小
std::cout << str << std::endl; // 输出 "Hello\0\0\0"
str.resize(3); // 缩小字符串大小
std::cout << str << std::endl; // 输出 "Hel"
- `reserve`: 预留空间
- 描述:`reserve` 函数用于预留字符串的存储空间,以避免在后续操作中重新分配内存。这对于减少动态内存分配的开销很有用。
cpp
std::string str;
str.reserve(100); // 预留至少能容纳100个字符的空间
str = "Hello, World!"; // 不会触发重新分配内存
请注意,以上示例仅供参考
一、STL简介
1.1什么是STL
STL (standard template libaray - 标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架
1.2STL版本
原始版本:
Alexander Stepanov 、 Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意
运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使
用。 HP 版本 -- 所有 STL 实现版本的始祖。
P. J. 版本:
由 P. J. Plauger 开发,继承自 HP 版本,被 Windows Visual C++ 采用,不能公开或修改,缺陷:可读性比较低,
符号命名比较怪异。
RW 版本:
由 Rouge Wage 公司开发,继承自 HP 版本,被 C+ + Builder 采用,不能公开或修改,可读性一般。
SGI 版本:
由 Silicon Graphics Computer Systems , Inc 公司开发,继承自 HP 版 本。被 GCC(Linux) 采用,可移植性好,
可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。 我们后面学习 STL 要阅读部分源代码,
主要参考的就是这个版本。
1.3STL六大组件
STL 共有容器、配接器、迭代器、空间配装器、算法、仿函数六大组件,其内部包含的具体内容如下:

1.4STL重要性
网上有句话说:"不懂STL,不要说你会C++"。STL是C++中的优秀作品,有了它的陪伴,许多底层的数据结构以及算法都不需要自己重新造轮子,直接使用即可,大大提高了解题和开发的效率;因此,STL 在笔试、面试以及工作中其都是一个被重点考察的对象
1.5如何学习STL
告诉大家一个英文文档的查询接口网站:cplusplus.com - The C++ Resources Network
(注:cplusplus 更新之后需要注册才能使用,我们可以点击右上角的 "Legacy version" 回到旧版,个人认为旧版的使用体验比新版要好),因为 cplusplus 更适合初学者,我们学习STL过程中遇到的任何函数接口、函数参数等等方面的内容都可以在 cplusplus 上通过搜索解决
阅读优秀的C++书籍:C++是一门比较难的语言,其中的细节非常多,我现在偶尔也会看STL源码剖析

想要电子版的可以来私聊我!!
二、什么是string??(本质上是一个类)
C语言中,字符串是以'\0'结尾的若干个字符的集合,为了操作方便,C语言 string.h 头文件提供了一些系列的库函数,但是这些库函数与字符串是分离开的,不符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
基于上面这些原因,C++标准库提供了 string 类,string 类中提供了各种函数接口,比如类的六个默认成员函数、字符串插入删除、运算符重载等等,我们可以使用 string 来实例化对象,然后通过 string 的各种接口来完成对该对象的各种操作
string 类的实现框架大概如下:
cpp
namespace std {
template<class T>
class string {
public:
// string 的各种成员函数
private:
T* _str;
size_t _size;
size_t _capacity;
//string 的其他成员变量,比如npos
};
}
注:严格来说 string 其实并不属于 STL,因为 string 出现的时间比 STL 要早(这也是为什么出现了.length(),和.size()俩个计算长度的原因),但是由于 string 的各种接口和 STL 中其他容器的接口非常类似,所以我们可以把 string 也当作 STL 的一种,放在一起学习
三、string的类模板(什么?string居然利用了模板??)
我们打开文档网址搜索string后会发现,string 其实是 basic_string 类模板使用字符类型 char 实例化得到的一个类(下面的英文一一定得耐着性子看完)
其实正是一个动态增长字符数组

那么什么是basic_string呢??
basic_string 是一个可以使用任意字符类型来实例化的类模板:


实在看不懂,我还是利用了翻译软件,发现居然是泛化!!!你问我什么是泛化?快去看我的模板博客!!模板初阶
所以,我们平时使用的 string 本质上是 basic_string<char>,我们不用自己显式实例化是因为 string 内部进行了 typedef:
typedef basic_string<char, char_traits, allocator> string
三、string的三种构造(拷贝构造也是构造奥)
string 提供了很多构造函数,我们只需要掌握其中最常用的几个就可以,其余的如果有需要再查询文档:(最常用的就是三个)

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

四、stirng的三种遍历方式
4.1 [ ] + 下标(operator[ ]的重载函数)
我们现在先不介绍 [ ] 怎么使用,我们先对 [ ] 的重载实现和优点做一个深入了解
在数组中,我们也可以用[ ]进行数据访问,但是他对于越界读和越界写的边界感很模糊,以下是我们自己写的数组重载方括号函数:
cpp
T& operator[](int index) {
// 使用assert检查越界
assert(index >= 0 && index < size);
return data[index];
}
这样更加保证了C++语言的封装性,更好更优秀;在string库中,也对方括号进行了重载

string中方括号的重载与上方类似,就是把assert的范围改成以下即可
index >= 0 && index < data.size()
总的来说,我们利用 [ ] 遍历访问的方式如下:
cpp
void test_string2()
{
string s1("1234");
//需求:让对象s1里面的每个字符都加1
//如果要让字符串的每个字符都加1,肯定离不开遍历,下面学习三种遍历string的方式。
//1.下标 + []
for (size_t i = 0; i < s1.size(); i++)
{
s1[i]++;//本质上
}
cout << s1 << endl;//GB2312兼容ascll编码,所以++后的结果为2345.
}
4.2基于范围for循环(C++11语法糖)
cpp
void test_string2()
{
//2.范围for
for (auto& ch : s1)//自动推导s1数组的每个元素后,用元素的引用作为迭代变量,通过引用达到修改s1数组元素的目的。
{
ch++;
}
cout << s1 << endl;
//在上面这种需求下,范围for看起来似乎更为方便
}


以上俩张图片摘自小羊C++入门范围for的讲解中
4.3迭代器遍历
\]只是一朝鲜,要想通用还得看我迭代器!
迭代器在使用的方式和行为上比较像指针,但是它和指针还是有区别的,它既有可能是指针,又有可能不是指针。在定义时要指定类域,譬如下面代码it1的定义,就需要指定类域里面的iterator类型。从下面代码可以看出,it1不仅可以访问而且还可以修改对象s1的内容。**并且除string外,我们头疼的list也可以照常使用iterator,这也验证了iterator的普适性**。
```cpp
list