【C++】String类:标准库介绍
目录
一.预备知识
1.auto关键字
2.范围for
3.迭代器
二.标准库里的string
1.string类的基本介绍
2.构造函数
编辑
3.访问及遍历操作
3.1 operator []
3.2 基于范围for
3.3 使用迭代器
4.迭代器
5.容量操作
5.1 size和length
5.2 capacity
5.3 reserve和resize
6.修改操作
6.1 operator+= 和 append
6.2 insert
6.3 erase
编辑
7.查找操作
7.1 find
7.2 rfind
7.3 substr
一.预备知识
1.auto关键字
在C++11中,标准委员会赋予了auto全新的含义:作为一个类型指示符来指示编译器在编译时期推导变量的类型。这使得代码更简洁,尤其是在处理复杂的类型时。
用法示例:
1.声明普通变量
auto x = 1; // x 的类型被推断为 int auto y = 1.11; // y 的类型被推断为 double
2.声明指针变量
int i = 10; auto p = &i; // p 的类型被推断为 int* auto* q = &i; // q 的类型同样被推断为 int*
3.声明引用类型
int j = 20; auto& r = j; // r 的类型被推断为 int&
4.在同一行声明多个变量
auto x1 = 1, x2 = 2; // 正确,x1 和 x2 的类型都推断为 int auto y1 = 1, y2 = 3.14; // 错误,y1 和 y2 的类型不同
5.auto不能直接声明未初始化变量(需要初始值设定)
6.auto不能作为函数的参数
// 错误用法 void func(auto n) {// ... }
7.auto不能直接声明数组
// 错误用法 auto arr[5]; // 错误,无法推断数组类型
auto常在范围for中使用,接下来就介绍范围for
2.范围for
对于一个有范围的集合而言,由程序员还说明循环的范围是多余的,有时候还容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号:分为两部分,冒号前是用于迭代的变量,冒号后是被迭代的范围,自动迭代,自动取数据,自动判断结束。
范围for可以作用到数组和容器对象(array、string、vector、list...)上进行遍历
int main()
{int array[] = { 1, 2, 3, 4, 5 };//遍历数组每一个值,都乘以2,结果为 2,4,6,8,10//自动识别类型,用引用能改变原值for (auto& e : array)e *= 2;//范围for遍历数组array并打印for (auto e : array)cout << e << ' ';cout << endl;//范围for遍历字符串str并打印string str("hello world");for (auto ch : str){cout << ch << ' ';}cout << endl;return 0;
}
范围for的底层很简单,容器的遍历实际上就是替换为迭代器,接下来就介绍迭代器
3.迭代器
迭代器是一种数据类型,在C++中,迭代器实际上是一种对象,它被设计用于在容器中进行元素的遍历和访问。迭代器为程序员提供了一种抽象的方式来访问容器的内容,而不用关心容器的底层实现细节。
例如以下用法,目前还没正式讲到,可以看作一个指针来进行理解:其中string::iterator就是string类的迭代器类型,it是迭代器的变量名,将其看作指针,begin就是开头处,end就是结尾处,*it就是解引用该指针指向的内容,it++使得指针指向下一个内容,如此,大概就是迭代器的遍历操作
int main()
{string s1 = "abcde";string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";it++;}return 0;
}
在string类的标准库和模拟实现中,会具体介绍并进行模拟实现,加深印象。
二.标准库里的string
1.string类的基本介绍
在C语言中,字符串是以'\0'结尾的字符数组,需要手动管理内存和处理字符串操作。在头文件string.h中提供了一系列库函数,如strlen、strcpy、strcat等来对字符串进行操作。但这些函数和字符串是分离的,需要手动管理内存,容易出现越界访问等问题。
因此,在C++标准库中,提供了string类,它封装了字符串操作,提供了丰富的成员函数和运算符重载,使得字符串的操作更加方便和安全。
实际上string类是C++标准库的一部分,学习标准库,是一定需要去读文档的,本文依照该string类的文档介绍进行:string - C++ Reference (plusplus.com)
string在底层实际是basic_string这个模板类使用char类型实例化得到的一个具体类,当然我们在使用时直接使用string即可,它本身就是basic_string<char>
2.构造函数
string作为一个类,构造函数是必不可少的,常用的如下几个:
构造函数名称 | 功能说明 |
---|---|
string() | 默认构造函数,构造空的string类对象,即空字符串 |
string(const string& s) | 拷贝构造函数 |
string(const char* s) | 用C-string(C风格的字符串)来构造 |
string(size_t n, char c) | string类对象中包含n个字符c |
#include<iostream>
using namespace std;
int main()
{string s1;string s2("abcdefg");string s3(10, 'a');string s4(s2);cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;return 0;
}
3.访问及遍历操作
3.1 operator []
重载下标操作符[ ],使得可以像访问数组一样使用下标来访问字符串中的某个字符,同时返回值是char&,这意味着我们还可以对该下标的字符进行修改等操作。
int main()
{string s1 = "abcde";//进行遍历,遍历方式类似于数组for (int i = 0; i < s1.size(); ++i){cout << s1[i] << " ";}cout << endl;//对下标为0的字符(即第一个字符)进行更改s1[0] = '0';cout << s1;return 0;
}
3.2 基于范围for
int main()
{string s1 = "abcde";//只能遍历for (auto e: s1){cout << e << " ";}cout << endl;//若要进行更改,加&引用for (auto& e : s1){e = 'a';cout << e << " ";}cout << endl;return 0;
}
3.3 使用迭代器
在遍历的实现中,更推荐使用迭代器,因为迭代器是大多数数据结构都拥有的,而[ ]不是都有的,使用[ ] 要求物理底层是连续的,如数组等。
int main()
{string s1 = "abcde";string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";it++;}return 0;
}
4.迭代器
迭代器是一种数据结构,在C++中,迭代器是一种对象,它被设计用于在容器中进行元素的遍历和访问。迭代器为程序员提供了一种抽象的方式来访问容器中的元素,而不用关心容器的底层实现细节。
在string类中就有这四个比较重要的迭代器:
迭代器名称 | 功能说明 |
---|---|
begin() | 返回一个指向字符串中第一个字符的迭代器 |
end() | 返回一个指向字符串中最后一个字符的下一个位置的迭代器 |
rbegin() | 反向,返回一个指向字符串中最后一个字符的迭代器 |
rend() | 反向,返回一个指向字符串中第一个字符的前一个位置的迭代器 |
string类提供了很多类型的迭代器,包括正向迭代器(iterator)、常量正向迭代器(const_iterator)、反向迭代器(reverse_iterator)、常量反向迭代器(const_reverse_iterator)
- 正向迭代器(iterator):用于遍历可修改字符串的迭代器,可以通过begin()、end()方法来获取范围
- 常量正向迭代器(const_iterator):用于遍历不可修改的常量对象的迭代器,也可以通过begin()、end()方法获取范围
- 反向迭代器(reverse_iterator):用于反向遍历可修改的字符串的迭代器,可以通过rbegin()、rend()方法来获取范围
- 反向常量正向迭代器(const_reverse_iterator):用于反向遍历不可修改的常量对象的迭代器,也可以通过rbegin()、rend()方法获取范围
根据begin()的定义,可以发现这其实是一个重载,一个适用于非常量对象,一个适用于常量对象,返回的迭代器也因此不同,例如可以这样使用:
int main()
{string s = "abcde";const string cs = "abc";//会取寻找最合适的,此时非常量对象两者都可以,不过使用普通迭代器最合适string::iterator it = s.begin();//但是权限不能放大,只能缩小//不能使用普通迭代器去接收常量字符串的迭代器//因此用string::iterator cit = cs.begin()会报错//应该使用常量迭代器string::const_iterator cit = cs.begin();return 0;
}
其他的end();rbegin();rend()都是同理,此处不再赘述。
5.容量操作
函数名称 | 功能说明 |
---|---|
size() | 返回字符串有效字符长度(容器通用) |
length() | 返回字符串有效字符长度(字符串专属) |
capacity() | 返回当前分配给字符串的总空间大小 |
empty() | 检测字符串是否为空字符串 |
clear() | 清空字符串有效内容 |
reserve() | 为字符串预留空间 |
resize() | 将有效字符的个数改为n个,多出的空间用字符c填充 |
5.1 size和length
两者的作用完全相同:都是返回字符串的有效长度,但是length是只适用于字符串string类的,而size是通用于容器的。
5.2 capacity
capacity()用于返回当前字符串对象分配的储存空间大小(即容量),字符串是存在容量的,这个容量就是指在不重新分配内存的情况下,字符串可以存储的最大字符数。
值得注意的是,capacity()返回的是字符串分配的总空间大小,而不是当前字符串的实际长度,也就是说,capacity()的返回值会大于size()的返回值,因为容量是一定大于等于实际储存的字符长度的,例如:
5.3 reserve和resize
reserve有保留,预定的意思,功能就是为字符串预留至少n个字符的储存空间,也就是提前分配指定大小空间,好处是节约扩容成本。改变的是容量的大小,而不是实际有效字符的大小。
- 当n大于当前容量时,reserve就会重新分配内存(可能扩容到n但也可能按其他方式进行扩容到比n大的数目)
- 若n小于容量,有可能进行缩容也有可能不做处理,这取决于编译器和环境
但有一点是无可置疑的:reserve不会影响到字符串的实际大小与内容,size()的值一定不会变化
resize功能是调整字符串的实际大小为n。根据需要插入或删除字符,使得字符串的实际大小等于n
- 若n小于当前字符串的实际大小,那么多余的字符将被删除,只剩下前n个字符
- 若n大于当前字符串的实际大小,那么将用指定的字符c(不指定默认是'\0')来填充新增的部分
6.修改操作
函数名称 | 功能说明 |
---|---|
operator += | 在字符串后追加字符串 |
push_back | 在字符串后插入字符 |
append | 在字符串后追加字符串 |
insert | 插入字符(字符串) |
erase | 删除字符 |
6.1 operator+= 和 append
将+=进行重载,用于将当前字符串与另外一个字符串进行连接,方便快捷,当然append也能做到该功能。
6.2 insert
常用的两个, 1号是在pos这个下标位置前插入str字符串,2号是在pos下标前插入n个字符c
由于插入需要挪动数据,因此insert的效率其实并不高
6.3 erase
删除从下标pos出开始算起的len的字符,注意这里len的默认值是npos,需要补充说明一下npos
npos是C++中的一个静态成员变量,表示无效或不存在的位置。通常用于标识字符串查找等操作未找到匹配项的情况。npos的类型是size_t,值为-1,其补码就是全1,也就是最大的意思。
7.查找操作
函数名称 | 功能说明 |
---|---|
find | 在字符串中查找指定的字符或子串 |
rfind | 在字符串中从右往左查找指定的字符或子串 |
find_first_of | 在字符串中从左往右查找指定集合中的任意字符 |
find_last_of | 在字符串中从右往左查找指定集合中的任意字符 |
find_first_not_of | 在字符串中从左往右查找不在指定集合中的最后一个字符 |
find_last_not_of | 在字符串中从右往左查找不在指定集合中的最后一个字符 |
substr | 从字符串中提取子串 |
7.1 find
find用于返回 一个字符或一个字符数组或一个string对象 在string中首次出现的位置,并返回下标,如果找不到就返回npos
7.2 rfind
整体和find类似。不过是从后往前找,找到一个字符或一个字符数组或一个string对象最后一次出现的位置,如果找不到就返回 npos
7.3 substr
从pos位置处开始截取len长度(默认截取到最后),下面以得到文件后缀为例:
int main()
{string s1("test.c");//得到文件后缀//从前往后找到第一个.的位置size_t pos1 = s1.find('.');//如果找到了就截取if (pos1 != string::npos){string ret1 = s1.substr(pos1);cout << ret1 << endl;}//如果文件名含有.怎么办string s2("te.st.c");//使用rfind从后往前查找倒数第一个.size_t pos2 = s2.rfind('.');if (pos2 != string::npos){string ret2 = s2.substr(pos2);cout << ret2 << endl;}return 0;
}
由于string类函数是很丰富的,这里不可能全部一一讲解,更多的需要在使用时去查阅相应的文档即可:<string> - C++ Reference (cplusplus.com)
在下一篇文章中将会具体自己模拟实现string类来加深理解,欢迎持续关注,感谢观看
相关文章:

【C++】String类:标准库介绍
目录 一.预备知识 1.auto关键字 2.范围for 3.迭代器 二.标准库里的string 1.string类的基本介绍 2.构造函数 编辑 3.访问及遍历操作 3.1 operator [] 3.2 基于范围for 3.3 使用迭代器 4.迭代器 5.容量操作 5.1 size和length 5.2 capacity 5.3 reserve和resiz…...

MS523非接触式读卡器 IC
MS523 是一款应用于 13.56MHz 非接触式通信中的高集成 度读写卡芯片,它集成了在 13.56MHz 下所有类型的被动非接 触式通信方式和协议,支持 ISO14443A/B 的多层应用。 主要特点 高度集成的解调和解码模拟电路 采用少量外部器件&#…...
仓颉编程语言入门 -- Socket 编程与HTTP 编程概述
仓颉的 Socket 编程概述 在网络通信的广阔天地中,仓颉的Socket编程如同一座桥梁,连接着不同的计算设备,实现了基于传输层协议的数据传输。无论是追求稳定可靠的TCP,还是偏好轻量级、无连接的UDP,Socket都扮演着不可或…...

Oracle基本SQL操作-用户角色权限管理
一、用户权限管理 -- 创建锁定用户,此时用户不可用 create USER zhucl IDENTIFIED BY 123456 account lock; 会提示用户被锁定: -- 删除用户 drop user zhucl;-- 重新创建用户,不锁定 create user zhucl IDENTIFIED BY 123456 account unlo…...

Qt-信号和槽(8)
目录 信号的概念 Qt中的信号三要素 connect函数 connect的原型 connect的使用 信号函数和槽函数 参数匹配 close关闭槽函数 运行结果 第一个问题:怎么知道 手册使用 第二个问题,为什么可以直接传递函数指针 自定义槽函数 第一种自定义槽函…...

80.游戏的分辨率修改思路与分析
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:易道云信息技术研究院 上一个内容:79.游戏分析工具闪屏问题优化与数据被修改高亮 GAMEHACKER2.exe 工具下载地址ÿ…...

MaxKB(二):Ubuntu24.04搭建maxkb开发环境
接上文:windows10搭建maxkb开发环境(劝退指南) 上文在windows10环境搭建maxkb开发环境遇到各种坑,后面就转战ubuntu平台,果然比较顺利的完成开发环境搭建。当然遇到相关的问题还是可以参考上文《windows10搭建maxkb开发…...

c#实现数据导出为PDF的方式
PdfSharp vs iTextSharp: C#中PDF导出功能比较 PdfSharp 优点 轻量级:适合简单的PDF生成任务易于学习:API相对简单,学习曲线较缓开源:提供开源版本,可自由使用和修改纯C#实现:不依赖外部库或COM组件支持…...

【联想电脑】:使用拓展坞后转接HDMI,无法识别显示屏
项目场景: 作为一个嵌入式软件开发者,有两个外接屏幕,不足为奇。 但是在今天的使用电脑过程中,出现了接了一个拓展坞上面有HDMI接口,但是HDMI接口接上外接显示屏的时候电脑无法识别到,导致只有电脑直连的HD…...

Verilog刷题笔记53
题目: Fsm serialdata See also: Serial receiver Now that you have a finite state machine that can identify when bytes are correctly received in a serial bitstream, add a datapath that will output the correctly-received data byte. out_byte needs …...
GoFly快速开发后台框架-后端接口请求返回403提示码就跨域问题/请求端域名拦截问题
问题: 大家在本地开发或者部署后请求后端时返回403,只有一个问题就是存在请求端跨域问题。 解决办法: 解决这个问题很简单,跨域的就解决跨域就好了。 我们官方给大家统一解决办法是: 到后端配置文件resource/conf…...

设备实时数据采集:开启制造业智能化、自动化的新篇章
传统制造业在进行生产过程中,会涉及到设备实时数据采集需求,这些数据对于监控生产流程、优化生产效率、保证产品质量以及降低成本等方面至关重要。以下是一些常见的数据采集需求: 1.生产数据:包括生产数量、生产批次、生产速度等&…...

【python与java的区别-03(集合、字典)】
一、Set python: 集合(set)是一个无序的不重复元素序列。 集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。 可以使用大括号 { } 创建集合,元素之间用逗号 , 分隔, 或者也可以使用 set() 函数…...

Java继承
目录 一、继承概念 二、语法格式 三、类型及特性 四、关键字 4.1. super 4.2. super与this指针 4.3 final 关键字 一、继承概念 继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性 的基础上进…...

Kafka集群搭建的两种方式
目录 1. 依赖Zookeeper搭建集群 1. 下载Kafka二进制文件 2. 更改kafka配置 3. 启动Zookeeper集群和Kafka集群 4. 验证集群 1.创建主题 2. 检查主题是否存在 3. 创建生产者生产数据 4. 创建消费者消费数据 5. 检查Zookeeper中Kafka集群的元数据 2. 不依赖Zookeeper搭…...
两种变量初始化方法的区别
1. CarriageEntity carriageEntity new CarriageEntity()和 null的区别 1.1 CarriageEntity carriageEntity new CarriageEntity(); 初始化:这行代码创建了一个新的 CarriageEntity 对象,并将其引用赋值给 carriageEntity 变量。对象状态ÿ…...

群晖把硬盘共享给win10(虚拟机或物理机)的两种办法
1. 通过SMB共享 NAS地址:192.168.3.100 打开“此电脑”,在win10地址栏输入 \192.168.3.100\video,提示输入用户名、密码。在video文件夹右击,点击“映射网络驱动器” 在win10电脑上,复制文件到T盘上,在T盘…...
Java-Web面试题汇总
一、TCP 和 UDP 的区别 在网络通信中,TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)是两种常见的协议,它们在多个方面存在显著差…...

数字化技术分别有哪些,数字化技术特点和优势是什么?
随着企业数字化进程的加速,人工智能、工业互联网、低代码等底层技术正全面重塑企业运营生产体系,推动新的生产要素、研发范式和商业模式的建立。 这个变革过程不仅是对原有制造体系的颠覆,而且会影响各行各业的所有细分行业和产业链价值链…...

微服务CI/CD实践(一)环境准备及虚拟机创建
微服务CI/CD实践系列: 微服务CI/CD实践(一)环境准备及虚拟机创建 微服务CI/CD实践(二)gitlabs部署 微服务CI/CD实践(三)nexus3部署 微服务CI/CD实践(四)数据库,redis,n…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...