系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、字符串的插入与删除
-
- 1.1插入接口
-
- [1.1.1 push_back 接口](#1.1.1 push_back 接口)
- [1.1.2 append 接口](#1.1.2 append 接口)
- [1.1.3 operator += 重载运算符](#1.1.3 operator += 重载运算符)
- [1.1.4 insert 接口](#1.1.4 insert 接口)
- [1.2 删除接口](#1.2 删除接口)
-
- [1.2.1 erase 接口](#1.2.1 erase 接口)
- [1.2.2 pop_back 接口](#1.2.2 pop_back 接口)
- 二、字符串的修改替换
-
- [2.1 replace 接口(局部精准替换)](#2.1 replace 接口(局部精准替换))
- [2.2 swap 接口(整体互换)](#2.2 swap 接口(整体互换))
- [2.3 assign 接口(整体全覆盖)](#2.3 assign 接口(整体全覆盖))
- 三、字符串数据查找
-
- [3.1 find 接口](#3.1 find 接口)
- [3.2 find 衍生接口](#3.2 find 衍生接口)
- 三、非常用接口
-
- [4.1 c_str 接口](#4.1 c_str 接口)
- [4.2 substr 接口](#4.2 substr 接口)
- [4.3 operator+ 接口](#4.3 operator+ 接口)
- [4.4 getline 接口](#4.4 getline 接口)
- 总结
前言
本节我们继续来学习string这个容器,本节将继续围绕string的使用继续展开,如它的常用接口。让我们废话少说直接开始今天的讲解。
一、字符串的插入与删除
1.1插入接口
1.1.1 push_back 接口

该接口功能与名字相符,即在字符串的末尾添加一个字符**(只能是字符)。**
1.1.2 append 接口

这个append 接口其实也是string设计时冗余的接口,但还是讲解一下,做个了解即可。
| 编号 | 语法 | 说明 | 使用方法 |
|---|---|---|---|
| 1 | string& append (const string& str) | 末尾插入类型构造的对象 | 尾插string对象 |
| 2 | string& append (const string& str, size_t subpos, size_t sublen) | 尾插string部分 | 尾插string对象的pos位置起始len个长度 |
| 3 | string& append (const char* s) | 插入字符串 | 尾插字符串 |
| 4 | string& append (const char* s, size_t n) | 尾插部分字符串 | 尾插以开头为起点,len个长度 |
| 5 | string& append (size_t n, char c) | 尾插多个字符 | 尾插 n 个 'c' 字符 |
| 6 | template string& append (InputIterator first, InputIterator last) | 迭代器尾插 | 尾插一个string对象迭代器区间内容 |
| 7 | string& append (initializer_list il) | 初始化列表尾插 | 在尾部插入初始化列表的内容 |
1.1.3 operator += 重载运算符

这个是最好用、最常用的插入方式,直接记住即可。
1.1.4 insert 接口

这个接口与上面三个不同,支持任意位置插入,使用方法与上面的append类似,只是多了个pos的参数,指定插入位置。但是这个插入是非常麻烦的,插入需要O(n)的时间复杂度,还是要慎重使用这个接口。
1.2 删除接口
1.2.1 erase 接口

| 序号 | 语法 | 作用 |
|---|---|---|
| 1 | string& erase (size_t pos = 0, size_t len = npos) | 删除以pos为开始下标后len个长度 |
| 2 | iterator erase (const_iterator p) | 删除迭代器代表位置的字符 |
| 3 | iterator erase (const_iterator first, const_iterator last) | 删除迭代器区间的字符 |
该接口删除的时间复杂度也是O(n),多次使用会大量浪费cpu运算资源,对于这种接口需要谨慎使用。
1.2.2 pop_back 接口

尾删,没什么好讲的,跳过。
二、字符串的修改替换
在这个段落中主要讲解与字符串修改替换的有关接口,日常中也是会常常涉及。
2.1 replace 接口(局部精准替换)

| 序号 | 语法 | 作用 |
|---|---|---|
| 1 | replace (pos, len, str); | 用整个str替换以pos为下标len长度的区间的字符 |
| replace ( i1, i2, str); | 用整个str替换迭代器区间的字符 | |
| 2 | replace ( pos, len, str, subpos, sublen) | 用str的以subpos为索引len个长度的字符区间替换原pos下标索引len个长度的字符区间 |
| 3 | replace ( pos, len, s) | c风格的字符替换 |
| replace ( i1, i2, s) | c风格的字符迭代器区间替换 | |
| 4 | replace ( pos, len, s, n) | 用字符串前n个字符替换原以pos为起始索引len个长度的字符区间 |
| replace (const_iterator i1, const_iterator i2, const char* s, size_t n) | 上一版的迭代器字符区间替换 | |
| 5 | replace ( pos, len, n, c) | 用n个字符替换区间字符 |
| replace (i1, i2, n, c) | 用n个字符替换迭代器区间字符 | |
| 6 | template replace ( i1, i2, first, last); | 适配所有类型的迭代器区间替换 |
| 7 | replace ( i1, i2, initializer_list il) | 初始化列表的迭代器区间替换 |
这个接口常常与find接口配合使用,实现指定位置字符的替换。当然这个接口也可以通过operator += 来模拟实现,只是需要再创建一个string对象,replace在追加字符时会造成扩容和移动数据的巨大消耗。
2.2 swap 接口(整体互换)

这个swap接口,是存于string对象的swap,必须面对对象使用,而全局的swap如同函数可以直接swap交换。直接将两个string对象存储的所有数据交换。
2.3 assign 接口(整体全覆盖)

| 序号 | 语法 | 作用 |
|---|---|---|
| 1 | string& assign (const string& str) | 用str替换原string对象的内容 |
| 2 | string& assign (const string& str, size_t subpos, size_t sublen) | 用str指定部分替换原string对象的内容 |
| 3 | string& assign (const char* s) | c风格的字符串替换 |
| 4 | string& assign (const char* s, size_t n) | 取字符串s中前n个字符替换 |
| 5 | string& assign (size_t n, char c) | 用n个字符替换原string对象的内容 |
| 6 | template string& assign (InputIterator first, InputIterator last) | 用迭代器区间替换 |
| 7 | string& assign (initializer_list il) | 初始化列表里的字符替换 |
| 8 | string& assign (string&& str) noexcept | 移动赋值 |
代码使用示例
cpp
string a = "hello world";
s1.assign(a);
cout << s1 << endl;// 输出:hello world
string b = "abcdef"
s1.assign(b,1,3);
cout << s1 << endl;// 输出:bcd
s1.assign("hi");
cout << s1 << endl;// 输出:hi
char* p = "123456";
s1.assign(p, 3);
cout << s1 << endl; // 输出:123
s1.assign(5, '*');
cout << s1 << endl; // 输出:*****
string a = "abcdef";
// 取 a 中从 begin()+1 到 end()-1 的内容
s1.assign(a.begin() + 1, a.end() - 1);
cout << s1 << endl; // 输出:bcde
s.assign({'a', 'b', 'c', 'd'});
cout << s1 << endl; // 输出:abcd
string a = "move me";
s1.assign(move(a)); // 移动
cout << s1 << endl; // 输出:move me
cout << a << endl; // 输出:空字符串(内容被移走了)
三、字符串数据查找
3.1 find 接口

最常用的字符查找接口,可以查询到目标字符所在字符串的下标位置
| 序号 | 语法 | 作用 |
|---|---|---|
| 1 | size_t find (const string& str, size_t pos = 0) const noexcept | 从字符串的pos下标开始,向后查找子串str,无返回npos |
| 2 | size_t find (const char* s, size_t pos = 0) const | c风格的字串查找 |
| 3 | size_t find (const char* s, size_t pos, size_type n) const | 从字符串的pos下标开始,向后查找子串str的前n个字符,无返回npos |
| 4 | size_t find (char c, size_t pos = 0) const noexcept | 从字符串的pos下标开始,向后查找特点字符,无返回npos |
3.2 find 衍生接口

| 格式 | 作用 |
|---|---|
| rfind | 将find从尾部到头部的逆置使用 |
| find_first_of_ | 查找和首先出现相关的接口 |
| find_end_of_ | 查找和最后出现相关的接口 |
| find_first_not_of_ | 找第一个【不是】目标字符的位置 |
| find_end_not_of_ | 找第最后一个【不是】目标字符的位置 |
三、非常用接口
4.1 c_str 接口

兼容c语言的接口,将string类型转为c风格的字符串,如文件的读写。
4.2 substr 接口

将string对象的pos下标为起始、len长度分出字串,需要用string对象接收返回值。
4.3 operator+ 接口

加的设置重载为全局的,是为了处理类对象在加号右方的情况,因为对象的重载运算符第一个参数一定是类对象。
4.4 getline 接口

在直接流重载输入string对象时,会发生与c语言输入一样的情况------即以空格和换行符为标志中止读取缓冲区字符,因此只会读取到第一个空格前的内容。而getline接口则可以解决这个问题,因为它是以换行符为标准,甚至可以自定义标志符。
cpp
getline(cin,str,'*'); //读取到*后中止读取缓冲区
总结
ok,这就是我们要了解的string常用接口,下一节我们将关注于string的底层实现,感谢您的阅读如有问题请指出。