【C++初阶】六、STL---string

简介: 目录一、为什么学习string类1.1 C语言中的字符串1.2 字符串在OJ面试中二、标准库中的string类2.1 string 介绍2.2 编码格式三、string 类常用接口3.1 Member functions(成员函数)3.1.1 构造函数(Construct)3.1.2 赋值重载(operator=) ​编辑3.1.3 string类对象的容量操作(Capacity)3.1.4 string类对象的访问(Element access) 3.1.5 string对象的访问及遍历操作(Iterators)3.1.5 strin

目录

一、为什么学习string类

1.1 C语言中的字符串

1.2 字符串在OJ面试中

二、标准库中的string类

2.1 string 介绍

2.2 编码格式

三、string 类常用接口

3.1 Member functions(成员函数)

3.1.1 构造函数(Construct)

3.1.2 赋值重载(operator=) 编辑

3.1.3 string类对象的容量操作(Capacity)

3.1.4 string类对象的访问(Element access)

3.1.5 string对象的访问及遍历操作(Iterators)  

3.1.6 string类对象的修改(Modifiers)

3.1.7 string类对象的操作(String operations)

3.2 string类非成员函数(Non-member function overloads)


一、为什么学习string类

1.1  C语言中的字符串

       C语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便,C标准库中提供了一些 str 系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想(面向对象思想),而且底层空间需要用户自己管理,稍不留神可能还会越界访问

1.2 字符串在OJ面试中

       在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。

注:由于历史原因,string类并不归属到 STL 之中,但是 string类与 STL 很相像,就把 string类归属到 STL 中一起学习

学习 STL 一定要多翻阅 STL的官方文档查看详细解释 C++官网cppreference

image.png

但是官网的排布内容不是很好,推荐使用这个非官网的网站:cplusplus ,右上角切换到旧版体验更好

image.png

二、标准库中的string类

2.1 string 介绍

string类的文档介绍

image.png

  • 1. 字符串是表示字符序列的类
  • 2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性
  • 3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)
  • 4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)
  • 5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作
  3. string在底层实际是:basic_string 模板类的别名,typedef basic_stringstring
  4. 不能操作多字节或者变长字符的序列


      在使用string类时,必须包含#include头文件  以及 using namespace std以及多翻阅参考cplusplus 的标准文档 string

  • 这里为什么是  而没有 .h呢?
  • 因为 C语言中已经有一个 了,为了避免冲突和进行区别,所以使用  作为头文件

2.2编码格式

string 是 basic_string 类模板使用字符类型 char 实例化得到的一个类

image.pngimage.png

而且还以模板生成几个名字不同 string 类,这些类的主要区别在于编码方式的不同,链接

image.png

string 为什么要设计成模板呢?

因为编码格式的不同,一些字符存储所占用的空间不同

常见的一些编码格式:

(1)ASCII码,是美国设计的;ASCII码表是:计算机当中存的值,和字符的映射,但是只有256个字符的表示,用char表示

(2)Unicode,也叫做万国码。,Unicode是针对全世界的语言而设计的一种编码,常见的有utf-8utf-16 utf-32

(3)gbk,gbk是叫做国标码,是针对中文创建的一个编码

编码方式对 basic_string 的影响如下

  • char – 采用单字节编码;
  • char16_t – 采用双字节编码
  • char32_t – 采用四字节编码

image.png

这里我们以第一种进行学习,单字节编码格式的 string

平时使用的 string 本质上是 basic_string,  string 内部进行了 typedef

typedef basic_string<char, char_traits, allocator> string

-------------------我是分割线------------------  

下面介绍string类常用的接口 ,要熟练掌握,其余的用时查阅即可

三、string 类常用接口

3.1 Member functions(成员函数)

3.1.1 构造函数(Construct)

image.png

提供了很多构造函数,只需要掌握其中最常用的几个就可以了,其余的如果有需要再查询文档

(constructor)函数名称 函数功能
string() (重点) 构造空的string类对象,即空字符
string(const char* s) (重点) 用字符数组来构造string类对象
string(const string&s) (重点) 拷贝构造函数
string(size_t n, char c) 用n个c字符来构造string类对象

测试代码

voidTest_string()
{
strings1; // 构造空的string类对象s1cout<<"s1: "<<s1<<endl;
strings2("hello world"); // 用C格式字符串构造string类对象s2cout<<"s2: "<<s2<<endl;
strings3(s2); // 拷贝构造s3cout<<"s3: "<<s3<<endl;
}

运行结果

image.png

3.1.2 赋值重载(operator=)

image.png

测试代码

voidTestString()
{
strings1("hello");
strings2, s3, s4;
s2=s1;
s3="world";
s4=s2+s3;
cout<<"s2: "<<s2<<endl;
cout<<"s3: "<<s3<<endl;
cout<<"s4: "<<s4<<endl;
}

运行结果

image.png

至于析构函数(destructor)则简单了解即可,因为程序结束自动调用析构函数

3.1.3 string类对象的容量操作(Capacity

image.png

掌握最常用的几个就可以了,其余的如果有需要再查询文档

函数名称 功能说明
size(重点) 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty(重点) 检测字符串释放为空串,是返回true,否则返回false
clear(重点) 清空有效字符
reserve(重点) 为字符串预留空间**
resize(重点) 将有效字符的个数该成n个,多出的空间用字符c填充

(1)size && length

       size 和 length 的功能完全相同,这是早期 string 设计遗留的问题

测试代码

voidTestString()
{
strings1("hello");
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.length: "<<s1.length() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl;
strings2("aaaaa");
cout<<"s2: "<<s2<<endl;
cout<<"s2.empty: "<<s2.empty() <<endl;
s2.clear();//清空有效字符串cout<<"s2.clear后: "<<s2<<endl;
}

运行结果

image.png

(2)resize

       resize 函数用来调整字符串大小,它一共分为三种情况:

image.png

  1. n 小于原字符串的 size,此时 resize 函数会将原字符串的 size 改为 n,但不会改变 capacity
  2. 大于原字符串的  size,但小于其 capacity,此时 resize 函数会将 size 后面的空间全部设置为字符 c 或默认的‘\0’
  1. 大于原字符串的 capacity,此时 resize 函数会将原字符串扩容,然后将size 后面的空间全部设置为字符 c 默认的‘\0’  

测试代码

voidTestString()
{
strings1("hello world!");
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl;
s1.resize(20);
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl;
s1.resize(15);
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl;
s1.resize(5);
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl;
}

运行结果

image.png

(3) reserve

       reserve 用来扩容与预留空间,相当于C语言中的 realloc 函数,它分两种情况:

image.png

  • n 大于原字符串的 capacity,此时 reserve 函数会将 capacity 扩容到 n
  • n 小于等于原字符串的 capacity,capacity 容量不变 (不缩容)


注意区分 reserve 和 reverse

测试代码

voidTestString()
{
strings1("hello world!");
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl<<endl;
s1.reserve(5);
s1.reserve(15);
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl<<endl;
s1.reserve(30);
cout<<"s1: "<<s1<<endl;
cout<<"s1.size: "<<s1.size() <<endl;
cout<<"s1.capacity: "<<s1.capacity() <<endl;
}

运行结果

image.png

3.1.4 string类对象的访问(Element access

image.png

掌握 operator[] 使用即可,其它也是使用到了再查询文档

image.png

测试代码

voidTestString()
{
strings1="hello world!";
for (size_ti=0; i<s1.size(); ++i)
    {
cout<<s1[i] <<endl;
    }
}

运行结果

image.png

3.1.5 string对象的访问及遍历操作(Iterators)  

      Iterators 是 C++中的迭代器,可以把它当成指针来理解(string 和 vector),不是所有迭代器都是指针

image.png

也是老样子,掌握常用的几个即可,其它使用到再查询文档

函数名称 函数功能
begin() 返回一个指向字符串中第一个字符的迭代器
end() 返回一个指向字符串最后一个字符下一个位置(‘\0’)的迭代器
rbegin() 反向迭代器,返回一个指向字符串最后一个字符下一个位置(‘\0’)的迭代器
rend() 反向迭代器,返回一个指向字符串中第一个字符的迭代器

image.png

image.png

测试代码

voidTestString()
{
strings1="12345";
string::iteratorit=s1.begin();
while (it<s1.end())
    {
        (*it)++;
cout<<*it;
++it;
    }
}

运行结果

image.png

       反向迭代器就是正向迭代器反过来使用,不再演示。实际上,范围 for 的底层就是使用迭代器实现的

3.1.6 string类对象的修改image.pngModifiers


也是老样子,掌握常用的几个即可,其它使用到再查询文档

函数名称 功能说明
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+=(重点) 在字符串后追加字符串str

(1) operator+=

       operator+= 是运算符重载,用于向字符串尾插数据,支持尾插一个字符串以及尾插一个字符

image.png

测试代码

voidTestString()
{
strings1="hello";
strings2="world";
s1+=s2;
cout<<s1<<endl;
}

运行结果

image.png

(2)push_back 、append

image.png

image.png


push_back 是在字符串后尾插字符c,append 是在字符串后追加一个字符串,这些都与 += 类似,设计有些多余,不演示了

(3)insert 和 erase

       insert 函数用于向在字符串的 pos 处插入数据,erase 用来从 pos 位置开始向后删除 len 个字符,因为时间复杂度的问题,很少使用,有需要直接看文档,不演示了

3.1.7 string类对象的操作(String operations

image.png

老规矩,掌握常用的几个即可,其它使用到再查询文档

函数名称 功能说明
c_str(重点) 返回C格式字符串
find(重点) 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,然后将其返回

(1)c_str

       在某些场景中只支持对C形式的字符串,即字符数组进行操作,比如网络传输、fopen,而不支持对C++中的 string 对象进行操作,所以 string 提供了 c_str,用于返回C形式的字符串,即以 ‘\0’ 结尾的字符串

测试代码

voidTestString()
{
strings1="hello world";
constchar*str=s1.c_str();
cout<<str<<endl;
}

运行结果

image.png

(2)find

       find 用于返回 一个字符或一个字符数组或一个string对象 在 string 中首次出现的位置,如果找不到就返回 npos:

image.png

说明一下 npos,npos 是一个无符号数,npos = -1 即代表无符号的最大取值

image.png

测试代码

voidTestString()
{
strings1="hello world";
cout<<s1.find('o') <<endl;
cout<<s1.find("or") <<endl;
cout<<s1.find("a") <<endl;
}

运行结果

image.png

(3)rfind

       rfind 是从末尾开始找指定内容,与 find 查找方向相反,不演示了

image.png

(4)substr

       substr 返回一个新构造的字符串对象,从字符位置 pos 开始,跨越 len 个字符或直到字符串结尾

image.png

测试代码

voidTestString()
{
strings1="hello world!!";
cout<<s1.substr(0, 5) <<endl;
cout<<s1.substr(6, 6) <<endl;
}

运行结果

image.png

3.2 string类非成员函数(Non-member function overloads)

image.png

掌握常用的几个即可,其它使用到再查询文档

函数 功能说明
operator+ 尽量少用,因为传值返回,导致深拷贝效率低
operator>>(重点) 输入运算符重载
operator<<(重点) 输出运算符重载
getline(重点) 获取一行字符串
relational operators(重点) 大小比较

(1) relational operators

两个 string 对象之间的大小关系函数重载,直接使用就好了,不演示了

image.png

(2) operator>> 和 operator<<

流插入与流提取运算符重载,这两个重载的作用就是为了让 string 对象支持直接输出和输入

(3)getline

        C语言中的 scanf 函数和 C++ 中的 cin 都是以空格、换行等作为不同数据之间的分割标志的,即当它们遇到这些符号时就会停止读。C语言提供了 gets 函数来读取一行字符,C++ 则是提供了 getline 函数来读取一行字符,并且我们还可以自己指定结束标志符,不演示了

image.png

----------------我是分割线---------------

文章到这里就结束了,下一篇即将更新

相关文章
|
2月前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
77 5
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
59 2
|
3月前
|
C++ 容器
|
3月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
30 1
|
3月前
|
C++ 容器
|
3月前
|
C++ 容器
|
3月前
|
存储 C++ 容器
|
3月前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
56 4
|
3月前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
85 2
|
3月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(三)
【C++】C++ STL 探索:String的使用与理解