C++的string类
目录
- 1 string 类的介绍
- 2 string 类常用的接口
- 2.1 string 的构造函数
- 2.2 string 遍历时常用的接口
- 2.3 string 容量相关的接口
- 2.3.1 reserve
- 2.3.2 resize
- 2.4 string 增删改查相关的接口
- 2.4.1 push_back
- 2.4.2 append
- 2.4.3 operator+=
- 2.4.4 find
- 2.4.5 rfind
- 2.4.6 substr
- 2.5 其它接口
- 2.5.1 getline
string 类的文档:文档链接
1 string 类的介绍
string 是用来存储字符串的一个类,内部封装了许多对字符串进行操作的成员函数,方便用户进行使用
想要使用 string ,就需要在项目中包含头文件 string.h,又由于 string 位于命名空间 std 下,所以需要使用 using namespace std 来展开命名空间
#include <string> //头文件
using namespace std; //展开命名空间
int main()
{string str1;return 0;
}
2 string 类常用的接口
2.1 string 的构造函数
string 的常用构造函数主要有三个:
构造函数 | 说明 |
---|---|
string() | 无参构造函数,用于构造空字符串 |
string(const char* s) | 带参构造函数,可以通过 C 的字符串来构造 string 对象 |
string(const string& s) | 拷贝构造函数,可以通过已有的 string 对象来初始化另一个 string 对象 |
示例:使用上述的三个构造函数来构造 string 类型的对象
#include <string>
using namespace std;
int main()
{string str1; //无参构造string str2("hello world"); //通过 C 的字符串构造stringstring str3(str1); //拷贝构造return 0;
}
2.2 string 遍历时常用的接口
接口名称 | 说明 |
---|---|
begin() | 获取指向第一个位置的迭代器 |
end() | 获取指向最后一个字符的下一个位置的迭代器 |
rbegin() | 获取指向最后一个字符的迭代器 |
rend() | 获取指向第一个字符的前一个位置的迭代器 |
operator[] | []重载,使 string 可以通过下标来访问 |
size() | 获取字符串有效字符的个数 |
遍历 string 有三种方式:
- 使用下标遍历,也就是类似于 C 语言遍历字符串的方式
- 使用迭代器遍历,迭代器是类似于指针的工具,后续的每个 STL 容器都有自己的迭代器,用户可以通过 类型名::iterator 来获取容器的迭代器
- 使用 auto 关键字和范围 for 遍历,auto 关键字可以让编译器根据表达式来推演出变量的类型,不需要用户自己指定,auto 在函数中,可以作为返回值类型,但是不可以修饰形参,但是作为返回值要谨慎使用
使用下标遍历
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");for (size_t i = 0;i < str1.size();++i){cout << str1[i];}return 0;
}
使用迭代器遍历
正向迭代器
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");string::iterator it = str1.begin();while (it != str1.end()){cout << *it;it++;}cout << endl;return 0;
}
反向迭代器
在使用反向迭代器的时候,要注意迭代器的类型名变成了 reverse_iterator,并且在遍历时,迭代器需要进行++而不是- -
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");string::reverse_iterator rit = str1.rbegin();while (rit != str1.rend()){cout << *rit;rit++;}cout << endl;return 0;
}
使用 auto 和范围 for 遍历
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");//不修改元素for (auto ch : str1){cout << ch;}//需要修改元素时//for (auto& ch : str1)//{// cout << ch;//}cout << endl;return 0;
}
以这个方式遍历时,无法对字符串内的元素进行修改,如果想要修改,在 auto 后加上&即可,这样一来,ch 就是字符串元素的引用
2.3 string 容量相关的接口
接口名称 | 说明 |
---|---|
size() | 返回字符串有效元素个数 |
length() | 返回字符串有效元素个数 |
capacity() | 返回开辟的空间总大小 |
empty() | 判断字符串是否为空串,是空串返回 true,不是返回 false |
clear() | 清空字符串的字符 |
reserve() | 预留空间 |
resize() | 设置有效字符的个数 |
在这里着重说明一下 reserve() 和 resize()
2.3.1 reserve
reserve 的参数列表与返回值如下:
void reserve (size_t n = 0);
功能是为字符串预留空间,在预留空间时,它遵循以下原则:
- n > 当前字符串容量时,对字符串进行扩容,扩充容量至 n 或者更大,在 vs 中,扩充是按照 1.5 倍进行扩充
- n = 当前字符串容量时,不进行任何操作
- n < 当前字符串容量时,是否进行容量的缩小是不确定的,取决于编译器的实现,在 vs 中,不对容量进行缩减
进行空间的扩充时:
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");cout << "原大小: " << str1.capacity() << endl;str1.reserve(20);cout << "新大小: " << str1.capacity() << endl;cout << endl;cout << "原大小: " << str1.capacity() << endl;str1.reserve(40);cout << "新大小: " << str1.capacity() << endl;cout << endl;cout << "原大小: " << str1.capacity() << endl;str1.reserve(60);cout << "新大小: " << str1.capacity() << endl;cout << endl;return 0;
}
在 vs 中得到的结果如下:
可以看到,第一次扩充时,扩了两倍,但是后续都是 1.5 倍
进行空间的缩减时:
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");cout << "原大小: " << str1.capacity() << endl;str1.reserve(5);cout << "新大小: " << str1.capacity() << endl;return 0;
}
在 vs 中,得到的结果是:
因此可以得到,在 vs 中,不会对空间缩减
2.3.2 resize
resize 的参数列表和返回值如下:
void resize (size_t n);
void resize (size_t n, char c);
它的功能是将字符串的有效字符个数改成 n 个,在更改时,遵循以下的规则:
- n > 当前字符串有效字符个数,那么就会添加字符至 n 个,如果有给定参数 c,那么就用 c 来进行补充,否则使用 ‘\0’
- n = 当前字符串有效字符个数,就不进行任何操作
- n < 当前字符串有效字符个数,就会将字符串缩短至 n ,移除多余字符
增加有效字符:
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");str1.resize(20, 'a');cout << str1;return 0;
}
减少有效字符:
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");str1.resize(5);cout << str1;return 0;
}
2.4 string 增删改查相关的接口
接口名称 | 说明 |
---|---|
push_back() | 在字符串中尾插字符 c |
append() | 在字符串中尾插字符串 |
operator+=() | 在字符串后尾插字符或字符串 |
find() | 在字符串中从 pos 位置自前向后查找字符或字符串 |
rfind() | 在字符串中从 pos 位置自后向前查找字符或字符串 |
substr() | 返回子串 |
2.4.1 push_back
push_back 的参数列表与返回值如下:
void push_back (char c);
作用是在字符串中尾插字符 c
示例:在字符串 str1 中尾插一个字符
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");str1.push_back('a');cout << str1 << endl;return 0;
}
2.4.2 append
append 的参数列表与返回值如下:
string& append (const char* s);
string& append (const string& str);
作用是在字符串中尾插字符串 s 或 str
示例:分别在 str1 和 str2 后尾插字符串
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");string str2("hello bit");str2.append(str1);cout << str2 << endl;str1.append("hello bit");cout << str1 << endl;return 0;
}
2.4.3 operator+=
operator+= 的参数列表与返回值如下,它重载了 += 运算符:
string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);
它相当于是 append 和 push_back 的结合体,既可以尾插字符,也可以尾插字符串
示例:分别在 str1 后尾插字符,在 str2 后尾插字符串
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");string str2("hello bit");str1 += 'a';str2 += "hello world";cout << str1;cout << str2;return 0;
}
2.4.4 find
find 的参数列表与返回值如下:
size_t find (const string& str, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;
size_t find (char c, size_t pos = 0) const;
作用是从 pos 位置开始向后查找字符或字符串,返回字符或字符串的位置
示例:在 str1 中查找单词 hello 和字符 h,假设 str1 为 hello world
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");cout << str1.find('h') << endl;cout << str1.find("hello") << endl;return 0;
}
2.4.5 rfind
rfind 的参数列表与返回值如下:
size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;
size_t rfind (char c, size_t pos = npos) const;
作用是从 pos 位置开始,向前查找字符或字符串,返回它的位置,这里的 npos 值为 -1,由于是 size_t,所以最终的值为 int 最大值,相当于默认从最后开始
示例:在 str1 中查找单词 hello 和字符 h,假设 str1 为 hello world
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");cout << str1.rfind('h') << endl;cout << str1.rfind("hello") << endl;return 0;
}
2.4.6 substr
substr 的参数列表与返回值如下:
string substr (size_t pos = 0, size_t len = npos) const;
作用是返回 pos 位置开始,长度为 len 的子串,若 len 没有指定,则默认到字符串末尾
示例:取出 str1 中的子串 hello,假设 str1 为 hello world
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1("hello world");cout << str1.substr(0, 5) << endl;return 0;
}
2.5 其它接口
接口名称 | 说明 |
---|---|
operator<<() | << 运算符的重载,使 string 类型的对象可以直接通过 << 输出 |
operator>>() | >> 运算符的重载,使 string 类型的对象可以直接通过 >> 接收输入 |
getline() | 接收输入的字符串 |
relational operators | 用于字符串的比较,重载了 <,>,<=,>=,==,!= 运算符 |
主要来说明一下 getline()
2.5.1 getline
substr 的参数列表与返回值如下:
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
作用是接收输入的字符串,在接收时,默认以遇到 ‘\n’ 作为结束,若用户指定了参数 delim,则以指定的字符作为结束
与 >> 重载不同的是, >> 重载遇到空白字符就认为结束
示例:接收 hello world 至 str1 内
#include <iostream>
#include <string>
using namespace std;
int main()
{string str1;getline(cin, str1);cout << str1 << endl;return 0;
}