当前位置: 首页 > news >正文

【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)

  1.  正向迭代器(iterator):用于遍历可修改字符串的迭代器,可以通过begin()、end()方法来获取范围
  2. 常量正向迭代器(const_iterator):用于遍历不可修改的常量对象的迭代器,也可以通过begin()、end()方法获取范围
  3. 反向迭代器(reverse_iterator):用于反向遍历可修改的字符串的迭代器,可以通过rbegin()、rend()方法来获取范围
  4. 反向常量正向迭代器(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 非接触式通信中的高集成 度读写卡芯片&#xff0c;它集成了在 13.56MHz 下所有类型的被动非接 触式通信方式和协议&#xff0c;支持 ISO14443A/B 的多层应用。 主要特点  高度集成的解调和解码模拟电路  采用少量外部器件&#…...

仓颉编程语言入门 -- Socket 编程与HTTP 编程概述

仓颉的 Socket 编程概述 在网络通信的广阔天地中&#xff0c;仓颉的Socket编程如同一座桥梁&#xff0c;连接着不同的计算设备&#xff0c;实现了基于传输层协议的数据传输。无论是追求稳定可靠的TCP&#xff0c;还是偏好轻量级、无连接的UDP&#xff0c;Socket都扮演着不可或…...

Oracle基本SQL操作-用户角色权限管理

一、用户权限管理 -- 创建锁定用户&#xff0c;此时用户不可用 create USER zhucl IDENTIFIED BY 123456 account lock; 会提示用户被锁定&#xff1a; -- 删除用户 drop user zhucl;-- 重新创建用户&#xff0c;不锁定 create user zhucl IDENTIFIED BY 123456 account unlo…...

Qt-信号和槽(8)

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

80.游戏的分辨率修改思路与分析

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

MaxKB(二):Ubuntu24.04搭建maxkb开发环境

接上文&#xff1a;windows10搭建maxkb开发环境&#xff08;劝退指南&#xff09; 上文在windows10环境搭建maxkb开发环境遇到各种坑&#xff0c;后面就转战ubuntu平台&#xff0c;果然比较顺利的完成开发环境搭建。当然遇到相关的问题还是可以参考上文《windows10搭建maxkb开发…...

c#实现数据导出为PDF的方式

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

【联想电脑】:使用拓展坞后转接HDMI,无法识别显示屏

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

Verilog刷题笔记53

题目&#xff1a; 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提示码就跨域问题/请求端域名拦截问题

问题&#xff1a; 大家在本地开发或者部署后请求后端时返回403&#xff0c;只有一个问题就是存在请求端跨域问题。 解决办法&#xff1a; 解决这个问题很简单&#xff0c;跨域的就解决跨域就好了。 我们官方给大家统一解决办法是&#xff1a; 到后端配置文件resource/conf…...

设备实时数据采集:开启制造业智能化、自动化的新篇章

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

【python与java的区别-03(集合、字典)】

一、Set python: 集合&#xff08;set&#xff09;是一个无序的不重复元素序列。 集合中的元素不会重复&#xff0c;并且可以进行交集、并集、差集等常见的集合操作。 可以使用大括号 { } 创建集合&#xff0c;元素之间用逗号 , 分隔&#xff0c; 或者也可以使用 set() 函数…...

Java继承

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

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(); 初始化&#xff1a;这行代码创建了一个新的 CarriageEntity 对象&#xff0c;并将其引用赋值给 carriageEntity 变量。对象状态&#xff…...

群晖把硬盘共享给win10(虚拟机或物理机)的两种办法

1. 通过SMB共享 NAS地址&#xff1a;192.168.3.100 打开“此电脑”&#xff0c;在win10地址栏输入 \192.168.3.100\video&#xff0c;提示输入用户名、密码。在video文件夹右击&#xff0c;点击“映射网络驱动器” 在win10电脑上&#xff0c;复制文件到T盘上&#xff0c;在T盘…...

Java-Web面试题汇总

一、TCP 和 UDP 的区别 在网络通信中&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是两种常见的协议&#xff0c;它们在多个方面存在显著差…...

数字化技术分别有哪些,数字化技术特点和优势是什么?

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

微服务CI/CD实践(一)环境准备及虚拟机创建

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

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...