这一篇博客,我们正式进入STL中的容器的字符串类的学习,C++标准模板库(STL)中的std::string
类是一个用于表示和操作字符串的类。它封装了动态分配的字符数组,提供了丰富的成员函数来进行字符串的操作,例如拼接、查找、替换、比较等。std::string
类还支持运算符重载,如+
用于字符串拼接,==
用于字符串比较,[]
用于访问字符等。它简化了C风格字符串的处理,使得字符串操作更加安全和便捷。我们学习主要是从两个方面学习:1、如何使用它。2、底层的原理。3、模拟实现。
目录
一、为什么学习string类?
1.1 C语言中的字符串
C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。
二、标准库中的string类
2.1 string类(了解)
- 字符串是表示字符序列的类
- 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
- string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信 息,请参阅basic_string)。
- string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits 和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
- 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
2.2 总结
1. string是表示字符串的字符串类,它就是一个自定义类型,可以用它来实例化字符串类对象。
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作成员函数以及描述这个字符串类属性的一些成员变量。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string string;
4. 不能操作多字节或者变长字符的序列。
在使用string类时,必须包含#include头文件(#include<string>)以及using namespace std;
2.3 string类的常用接口说明(最常用的接口)
2.3.1 string类对象的常见构造函数
#include <iostream>
#include <string> //必须要加这个头文件,因为标准库std它是分文件写的
using namespace std; //string类的实现都在std标准命名空间下
int main()
{
string s1; //1、实例化s1对象,无参构造函数
string s2("hello"); //2、实例化s1对象,带参构造函数
string s3(s2); //3、拷贝构造函数
string s4(10,'a'); //4、带参的拷贝构造函数,字符串初始化为10个a
string s5="hello"; //注意:这里是先用字符串"world"构造出一个临时的字符串对象,然后用这个临时的对象再去拷贝构造s5这个对象!然后被编译器直接优化成一步:直接去构造s5对象!它和第2个是等价的!
string s6=s2; //注意:这里看起来是赋值,其实是调用拷贝构造函数!
cout<< s1 << endl; //这里打印是空串,是因为C++STL中的string设计中默认会给字符串加上'\0'
cout<< s2 << endl;
cout<< s3 << endl;
cout<< s4 << endl;
cout<< s5 << endl;
cout<< s6 << endl;
s1 = s2; //这里是赋值运算符重载(string类已经实现好的)
cout<< s1 << endl;
return 0;
}
/*************************字符串的插入***************************************/
int main()
{
string s("12345");
s.push_back('6'); //字符串尾部插入单个字符
s.append("78"); //字符串尾部插入字符串
下面是使用运算符重载的方式:
s+='1'; //字符串尾部插入单个字符
s+="2222"; //字符串尾部插入字符串
cout<< s <<endl;
由此可见:字符串的插入使用+=运算符更加的方便!!推荐使用
string s;
s+= "zhang";
s+='-';
s+="子杰";
cout<<s<<endl;
return 0;
}
/****************************实现字符串转整型******************************/
int main()
{
string s("12345");
int val=0;
for(int i=0; i<s.size(); i++)
{
//cout<<s[i]<<" "; [ ]遍历字符串
val*=10;
val+=s[i]-'0'; //这里是字符相减,其实就是ASCII码相减,1的ASCII码为49,0的ASCII码为48
}
cout<<val<<endl;
return 0;
}
/************************************************************************/
2.3.2string类对象的访问及遍历操作
字符串遍历方式1:
for循环结合[ ]的运算符重载,就可以像C语言中遍历字符数粗的方式一样遍历这个字符串对象。这种方式也是使用最多的。
/*****************字符串的遍历方式1:for+operator[]下标***********************************/
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello");
s1 += ' ';
s1 += "world";
cout <<s1<< endl;
//对字符串进行写操作
for (int i = 0; i < s1.size(); i++)
{
s1[i] += 1;
//这里可不是重载+=运算符,这里先结合左边的[]运算符重载,返回指定i位置的字符,然后将其加1.
}
//对字符串进行读操作
for (int i = 0; i < s1.size(); i++)
{
cout << s1[i] << " " ;
}
cout << endl;
return 0;
}
/*********************************