一起来看看C++STL容器之string类
前言
为什么学习string类:
在C语言中,字符串是以'\0'结尾的集合,为了操作方便,在C标准库中提供一些str系列的函数(strstr,strcmp,strcpy……),但是这些库函数和字符串时分离的,不太符合oop的思想。稍不留神就会造成越界访问。
在OJ题中,有关字符串的题目基本以string的形式出现,而且在常规的工作中,为了简单,方便,快捷,基本都是使用string类,很少有人会使用C库中的字符串操作函数。
1.标准库中的string类
1.string类是表示字符串的字符种类。
2.该类的接口与常规容器的接口基本相同,在添加一些专门用来操作string的常规操作。
3.string的底层是:basic_string模板类的别名。
4.不能操作多字节或者变长字符的序列。
在使用string的时候,必需包含头文件#include<string>以及using namespace std;
2.string类的常用接口说明
2.1 string对象的常见构造
string() | 构造空的string类对象 |
string(const char* str) | 以常量字符创为参数构造string类 |
string(size_t n,char ch) | string对象中包含了n个字符c |
string(const string& s) | 拷贝构造函数 |
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1;
string s2("CSDN");
string s3(4, 'A');
string s4(s2);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
}
[点击并拖拽以移动]
运行结果:
2.2 string类对象的容量操作
size | 返回字符串的有效长度 |
length | 和size一致,推荐使用size |
capacity | 返回总空间大小 |
clear | 清空有效字符,但是不对capacity有影响 |
reserve | 为字符串预留空间 |
empty | 判断字符串是否为空串,返回值为bool |
resize | 将有效字符的个数该成n个,多出的空间用字符c填充 |
2.2.1 reserve是如何开辟空间的
void reserve (size_t n=0)
void TestPushBack()
{
string s;
size_t sz = s.capacity();
for (int i = 0; i < 1000; ++i)
{
s.push_back('c');
if (sz != s.capacity())//当sz和_capacity不相等的时候,说明reserve已经增容了。
{
static int n = 1;
sz = s.capacity();
printf("第%d次开辟空间:_capacity=%d\n", n++, sz);
}
}
}
运行结果:
说明在VS的环境下,reserve每次开辟的空间是前一次空间的约1.5倍。
2.2.2 clear 和 empty
void clear ()
bool empty() const
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("CSDN");
cout << s1.capacity() << endl;
cout << s1.empty() << endl;
s1.clear();
cout << s1.capacity() << endl;
cout << s1.empty() << endl;
}
运行结果:
说明了clear只会清理有效的字符串,不会对空间的大小有影响,当clear后,empty的返回值为0,说明了此时的是s1是空字符串。
2.2.3 resize的用法
void resize(size_t n)
void resize(size_t n,char ch)
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("CSDN");
s1.resize(10, 'A');//输出的是------>CSDNAAAAAAAA
cout <<s1<< endl;
}
2.3 string类对象的访问以及遍历操作
operator[ ] | 返回 pos 位置的字符, const string 类对象调用 |
begin+end | begin 获取一个字符的迭代器 + end 获取最后一个字符下一个位置的迭代器 (正向迭代器) |
rbegin+rend | begin 获取一个字符的迭代器 + end 获取最后一个字符下一个位置的迭代器 (反向迭代器) |
范围for | C++11支持的更简洁的遍历方式 |
const_iterator begin()const
iterator begin()
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello CSDN");
auto it1= s1.begin();//正向迭代器
while (it1 != s1.end())//end指向的是最后一个元素的下一位
{
cout << *it1 << " ";
it1++;
}
cout << endl;
auto it2 = s1.rbegin();//反向迭代器
while (it2 != s1.rend())
{
cout << *it2 << " ";
it2++;
}
}
运行结果:
范围for的使用
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello CSDN");
for (auto ch :s1)
cout << ch<< " ";
}
本质上,范围for调用的是迭代器。
2.4 string类对象的修改操作
push_back | 尾插字符ch |
append | 尾插字符串str |
operator+= | 尾插字符ch/尾插字符串 |
c_str | 返回C格式字符串 |
find+npos | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置,npos是size_t的最大值 |
rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
2.4.1 push_back 和 append 以及operator+=
void push_back(char ch)
string& append(const char* str)
string& operator+=(char ch)
string& operator+=(const char* str)
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello ");
s1.push_back('C');
s1.append("SDN");
cout << s1 << endl;
string s2("hello ");
s2 += 'w';
s2 += "orld";
cout << s2 << endl;
}
运行结果:
operator +=可以尾插字符,也可以尾插字符串。实际上,operator +=尾插字符的时候,调用的是push_back,尾插字符串的时候,调用的是append。
2.4.2 find 和 rfind 以及 substr
size_t find(char c,size_t pos=0) const
size_t rfind(char c,size_t pos=npos)
string substr(size_t pos=0,size_t len=npos)
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello CSDN");
cout << s1.find('C') << endl;
cout << s1.rfind('C',0) << endl;//从pos=0处,即字符'h'往前找,找不到字符'C'返回的是npos
//npos是size_t中的最大值--->4294967295
cout << s1.rfind('C', 8) << endl;
cout << s1.substr(2, 3) << endl;//从字符串的第二个位置开始,截取len=3个字符
}
运行结果:
2.5 string非成员函数重载
operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
operator<< | 输出运算符重载 |
operator>> | 输出运算符重载 |
getline | 获取一行字符串 |
relational operator | 大小比较 |
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341