【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类来加深理解,欢迎持续关注,感谢观看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

备考2024年美国数学竞赛AMC10:吃透1250道真题和知识点(持续)

有什么含金量比较高的初中生数学竞赛吗&#xff1f;美国数学竞赛AMC10是个不错的选择。那么&#xff0c;如何备考AMC10美国数学竞赛呢&#xff1f;做真题&#xff0c;吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一。 通过做真题&#xff0c;可以帮助孩子找到真实竞赛…

Python使用Selenium进行Web自动化测试详解

目录 引言 一、Selenium简介 Selenium的核心组件 二、环境搭建 1. 安装Python 2. 安装Selenium库 3. 下载并配置浏览器驱动 三、基础用法 1. 启动浏览器 2. 定位页面元素 3. 元素操作 4. 等待元素加载 1. 测试目的 2. 测试步骤与代码实现 3. 注意事项 结论 引言…

ViT笔记学习

1.VIT ViT原理讲解 ViT结合代码 1.3 ViT模型架构 我们先结合下面的动图来粗略地分析一下ViT的工作流程&#xff0c;如下&#xff1a; 将一张图片分成patches将patches铺平将铺平后的patches的线性映射到更低维的空间添加位置embedding编码信息将图像序列数据送入标准Transfor…

labview经验分享1-任意16进制字符类型匹配

系列文章目录 1、任意16进制字符类型匹配 文章目录 系列文章目录问题导入实现任意16进制字符类型匹配在这里插入图片描述 总结 问题导入 labveiw的字符串匹配&#xff0c;使用的是正则表达式&#xff0c;可以让我们很方便的对字符串进行字符处理操作。 但是某些情况下&#…

【python】Python实现XGBoost算法的详细理论讲解与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

encoding with ‘idna‘ codec failed (UnicodeError: label empty or too long)

今天在使用Flask连接mysql的时候&#xff0c;遇到了一个报错&#xff1a;encoding with ‘idna’ codec failed (UnicodeError: label empty or too long) 网上查了一下说是字符集的问题&#xff0c;然后尝试修改了一下字符集&#xff0c;结果还是不行。 最后去翻阅SQLAlchemy…

使用docker-compose运行kafka及验证(无需zookpeer)

前言&#xff1a;要求安装docker-compose kafka镜像版本&#xff1a;apache/kafka:3.8.0 可能存在镜像拉不下来的情况&#xff1a; 1、vim /etc/docker/daemon.json {"data-root":"/data/docker","registry-mirrors": ["https://docker.m…

力扣第 411 场周赛题解

3258. 统计满足 K 约束的子字符串数量 I 给你一个 二进制 字符串 s 和一个整数 k。 如果一个 二进制字符串 满足以下任一条件&#xff0c;则认为该字符串满足 k 约束&#xff1a; 字符串中 0 的数量最多为 k。字符串中 1 的数量最多为 k。 返回一个整数&#xff0c;表示 s …

【数据结构-哈希前缀】力扣2845. 统计趣味子数组的数目

给你一个下标从 0 开始的整数数组 nums &#xff0c;以及整数 modulo 和整数 k 。 请你找出并统计数组中 趣味子数组 的数目。 如果 子数组 nums[l…r] 满足下述条件&#xff0c;则称其为 趣味子数组 &#xff1a; 在范围 [l, r] 内&#xff0c;设 cnt 为满足 nums[i] % mod…

JVM -垃圾回收器

本人在这篇文章中讲解了垃圾回收机制&#xff0c;这为前置知识 美团一面面经&#xff1a;Threadlocal&#xff08;线程局部变量的原理&#xff09;-&#xff1e;内存泄漏问题-&#xff1e;垃圾回收机制_threadlocal回收-CSDN博客 首先对前置知识漏洞做一个补充&#xff1a;ja…

open Euler22.03系统安装宝塔面板

环境&#xff1a;华为云open Euler22.03操作系统 配置&#xff1a;2核4G 1、安装宝塔面板。 登录弹性云服务器。 执行以下命令&#xff0c;下载并安装宝塔面板。 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh &&…

STM32裸机和RTOS中的线程安全问题及STM32cubeMX中的线程安全策略

STM32线程安全问题 术语“线程” 和“多线程” 适用于裸机和基于RTOS的应用程序&#xff0c;线程安全问题并不只存在于基于RTOS的应用程序中&#xff1b;裸机应用程序中也存在这个问题&#xff0c;在裸机应用程序中&#xff0c;中断服务程序允许调用C库函数。线程安全问题可能…

Python实现水果忍者(开源)

一、整体介绍&#xff1a; 1.1 前言&#xff1a; 游戏代码基于Python制作经典游戏案例-水果忍者做出一些改动&#xff0c;优化并增加了一些功能。作为自己Python阶段学习的结束作品&#xff0c;文章最后有源码链接。 1.2 Python主要知识&#xff1a; &#xff08;1&#xf…

Python爬虫——爬取某网站的视频

爬取视频 本次爬取&#xff0c;还是运用的是requests方法 首先进入此网站中&#xff0c;选取你想要爬取的视频&#xff0c;进入视频播放页面&#xff0c;按F12&#xff0c;将网络中的名称栏向上拉找到第一个并点击&#xff0c;可以在标头中&#xff0c;找到后续我们想要的一些…

qt-15综合实例(电子时钟)-多态重写鼠标单击和移动事件

综合实例-电子时钟 知识点digiclock.hdigiclock.cppmain.cpp运行图 知识点 setWindowOpacity(0.5);//设置窗体透明度 QTimer* Timer new QTimer(this);//新建一个定时器 connect(Timer,SIGNAL(timeout()),this,SLOT(ShowTime())); Timer->start(1000);//启动定时器 digic…

稚晖君发布5款全能人形机器人,开源创新,全能应用

8月18日&#xff0c;智元机器人举行“智元远征 商用启航” 2024年度新品发布会&#xff0c;智元联合创始人彭志辉主持并发布了“远征”与“灵犀”两大系列共五款商用人形机器人新品——远征A2、远征A2-W、远征A2-Max、灵犀X1及灵犀X1-W&#xff0c;并展示了在机器人动力、感知、…

猫头虎分享:练习提示词Prompt有什么好方法?提高Prompt水平和质量

猫头虎是谁&#xff1f; 大家好&#xff0c;我是 猫头虎&#xff0c;别名猫头虎博主&#xff0c;擅长的技术领域包括云原生、前端、后端、运维和AI。我的博客主要分享技术教程、bug解决思路、开发工具教程、前沿科技资讯、产品评测图文、产品使用体验图文、产品优点推广文稿、…

深扒大模型微调密码 - 从入门到技术小白都能看懂的神操作

朋友们&#xff0c;你们有没有听说过"大模型"和"微调"这两个概念呢&#xff1f;别着急,我们今天就来好好聊一聊! 想象一下,你有一个非常勤奋的小助理,它会尽最大努力帮你完成各种任务。不过有时候,它的知识储备和能力肯定有限,所以你得适时给它一些专门的…

树莓派5 笔记25:第一次启动与配置树莓派5_8G

今日继续学习树莓派5 8G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 与 python 版本如下&#xff1a; 今日购得了树莓派5_8G版本&#xff0c;性能是同运…

springboot航班进出港管理系统--论文源码调试讲解

第2章 开发环境与技术 本章节对开发航班进出港管理系统管理系统需要搭建的开发环境&#xff0c;还有航班进出港管理系统管理系统开发中使用的编程技术等进行阐述。 2.1 Java语言 Java语言是当今为止依然在编程语言行业具有生命力的常青树之一。Java语言最原始的诞生&#xff…