✨✨欢迎大家来到Celia的博客✨✨
🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉
所属专栏:C++
目录
一、string类简介
在C++中,string类可以简单理解为数据类型为char的顺序表。类中的主要成员变量有三个:
- capacity:总容量
- size:储存的元素个数
- 指针:指向动态开辟的空间
string类定义在命名空间std中,类中定义了许多成员函数来管理动态开辟的空间。
二、迭代器和范围for
迭代器是一种设计模式,实质上是一个类的对象,这个对象可以帮助我们遍历容器(C++中的概念,例如双向带头链表list,顺序表vector等)。由于某些数据结构的存储顺序在内存中不是连续的(比如链表),在C语言中,遍历这种数据结构通常需要我们自己去实现具体的逻辑,而迭代器则为这些数据结构的遍历提供了统一的标准。
迭代器的使用类似于指针,可以前后移动以及解引用。迭代器支持这些操作是因为迭代器类中重载了 ++, --, * 等运算符,这些重载运算符函数中实现了该迭代器具体迭代的对象相应的遍历逻辑。所以调用该重载函数就相当于让该函数帮助我们来完成具体的遍历逻辑,而我们只需要去让迭代器前后移动以及解引用迭代器就可以了。
所有的容器中,都会实现begin(), end() 等返回值为迭代器的函数,该函数被对象调用,返回不同“位置”的迭代器对象。迭代器类型名为 iterator ,该类型在容器的类中被重命名,所以需要指定类域来访问迭代器类型。
具体容器类 :: iterator = 对象.begin();
迭代器类型有:
- iterator --- 普通迭代器
- reverse_iterator --- 反向迭代器
- const_iterator --- 普通迭代器(对象被const修饰)
- const_reverse_iterator --- 反向迭代器(对象被const修饰)
迭代器函数有:
- begin --- end --- 返回普通迭代器
- rbegin --- rend --- 返回反向迭代器
- cbegin --- cend --- 返回普通迭代器(const修饰)
- crbegin --- crend --- 返回反向迭代器(const修饰)
(反向迭代器++相当于向前移动,也就是说,反向迭代器的使用形式与普通迭代器没有区别,但可以反向遍历)
例如:
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<int> l; //创建链表
l.push_back(1); //插入数据
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
list<int>::iterator it = l.begin();
while (it != l.end())
{
cout << *it << ' ';
it++;
}
cout << endl;
list<int>::reverse_iterator rit = l.rbegin();
while (rit != l.rend())
{
cout << *rit << ' ';
rit++;
}
return 0;
}
范围for实际上就是底层调用了迭代器的遍历方式:
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<int> l; //创建链表
l.push_back(1); //插入数据
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
for (auto x : l)
cout << x << ' ';
return 0;
}
范围for会将l对象中的所有值依次放入x中,aoto是一个关键字,编译器会自动推导变量类型。
三、string类的常用成员函数介绍
3.1 构造函数
- string();
默认构造函数,构造一个空串,长度为0。- string (const string& str);
拷贝构造,使用一个现有string对象构造。- string (const string& str, size_t pos, size_t len = npos);
使用现有字符串的一个区间来构造。(npos是一个很大的数,通常表示字符串末尾)- string (const char* s);
使用一个指针指向的字符数组来构造。- string (const char* s, size_t n);
使用指针指向的字符数组中复制前n个字符。- string (size_t n, char c);
复制相同的n个字符。
#include<iostream>
using namespace std;
int main()
{
//1
string s1;
//2
string s2("abcdef");//现有对象
string s3(s2);
//3
string s4(s2, 1, 4);
//4
string s5("12345");
//5
string s6("12345", 3);
//6
string s7(5, 'x');
return 0;
}
3.2 容量相关函数
- size();
返回元素个数。- void resize (size_t n);
void resize (size_t n, char c);
将字符串的大小调整为 n 个字符的长度。
如果 n 小于当前字符串长度,则当前值将缩短为其前 n 个字符,并删除第 n个字符之外的字符。
如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,以达到 n 的大小。如果指定了 c,则新元素将全部初始化为 c ,否则,它们的值为缺省值(‘\0’ 字符)。- capacity();
返回容量。- void reserve (size_t n = 0);
请求更改容量请求将字符串容量调整为n。
如果 n 大于当前字符串容量,则该函数会导致容器将其容量增加到 n 个字符(或更大)。
在所有其他情况下,它被视为一个非约束性请求(不同编译器的实现不同)。
此函数对字符串长度没有影响,并且不能更改其内容。- clear();
清空字符串,使字符串长度为0。- empty();
判断字符串是否为空。
using namespace std;
int main()
{
string s("12345");
cout << "string:" << s << endl; //运算符重载打印string对象
cout << "size:"<< s.size() << endl;
cout << "capacity:"<< s.capacity() << endl;
s.reserve(20);
cout << "capacity:"<< s.capacity() << endl;
s.resize(3);
cout << "capacity:" << s.size() << endl;
cout << "string:" << s << endl;
s.clear();
cout << s.empty() << endl;
return 0;
}
3.3访问函数
- operator[](size_t pos);
运算符重载函数,返回字符串pos位置的字符引用。- at(size_t pos);
返回字符串中pos位置的字符引用。- back();
返回字符串中最后一个字符的引用。- front();
返回字符串中第一个字符的引用。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s("abcd");
cout << s[0] << endl;
cout << s.at(0) << endl;
cout << s.front() << endl;
cout << s.back() << endl;
return 0;
}
3.4 其他修饰函数
- operator+=
在原有基础上拼接一个字符/字符串/string对象。- append()
和1作用相同。- push_back();
尾插一个字符。- pop_back();
尾删一个字符。- insert();
插入字符/字符串。- erase();
擦除字符串。- swap();
交换两个string对象的值。- c_str();
返回字符串头指针(一般为了与C风格的代码交互)。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s("abcd");
cout << s << endl;
s += "123";
cout << s << endl;
s.append("456");
cout << s << endl;
s.push_back('?');
cout << s << endl;
s.pop_back();
cout << s << endl;
s.insert(0, "***");
cout << s << endl;
s.erase(0, 3);
cout << s << endl;
cout << s.c_str() << endl;
return 0;
}
3.5 迭代器相关函数
- begin();
返回一个迭代器,该迭代器指向字符串的第一个字符。- end();
返回一个迭代器,该迭代器指向字符串的末尾(最后一个字符的下一个位置)。- rbegin();
返回一个反向迭代器,指向字符串的最后一个字符(即其反向开头)。增加迭代器会使它们朝向字符串的开头。- rend();
返回一个反向迭代器,指向字符串的第一个字符(即反向结尾)。- cbegin();
返回常对象的迭代器,该迭代器指向字符串的第一个字符。- cend();
返回常对象的迭代器,该迭代器指向字符串的末尾(最后一个字符的下一个位置)。- crbegin();
返回常对象的反向迭代器,指向字符串的最后一个字符(即其反向开头)。- crend();
返回常对象的反向迭代器,指向字符串的第一个字符(即反向结尾)。
#include<iostream>
using namespace std;
int main()
{
string s1("12345");
const string s2(s1);
cout << "正向迭代器: ";
string::iterator it = s1.begin();
while (it < s1.end())
{
cout << *it << ' ';
it++;
}
cout << endl;
cout << "反向迭代器: ";
string::reverse_iterator rit = s1.rbegin();
while (rit < s1.rend())
{
cout << *rit << ' ';
rit++;
}
cout << endl;
cout << "常量正向迭代器: ";
string::const_iterator cit = s2.cbegin();
while (cit < s2.cend())
{
cout << *cit << ' ';
cit++;
}
cout << endl;
cout << "常量反向迭代器: ";
string::const_reverse_iterator crit = s2.crbegin();
while (crit < s2.crend())
{
cout << *crit << ' ';
crit++;
}
return 0;
}
更多成员函数及用法请参考: https://legacy.cplusplus.com/reference/string/string/?kw=string