STL解析——String类详解(使用篇)

article/2025/8/3 23:19:17

目录

sring接口解析

1.string简介

2.默认成员函数

2.1构造函数

2.2析构函数

2.3赋值重载

 3.迭代器

3.1初识迭代器

3.2迭代器的使用

3.3特殊迭代器

3.4范围for

4.大小接口

4.1字符长度相关接口

4.2空间大小相关接口

5.其他常用接口

 5.1operator[ ]

5.2增

 5.3查

5.4导出


sring接口解析

1.string简介

在C语言中字符串底层实际是以'\0'结尾的字符数组,而这样操作方式并不是很方便,因此C++中将字符串封装成了独立的sring类,下面就来详细了解下string类的使用。

以下内容均参考https://legacy.cplusplus.com/

2.默认成员函数

2.1构造函数

在C++11标准中,编译器提供的构造函数如下:

(1) 默认构造:创建空字符串,并将所有成员变量初始化。下面进行代码演示,并顺便调试观察string的成员变量:

#include<iostream>
#include<string>using namespace std;//初始化
void Stringtest01()
{string s1;cout << s1 << endl;
}

调试结果如下:

可以看到string类中除了提供底层的字符数组,并且提供了大小(size),以及空间大小(capacity)成员,后面的两个成员变量主要与其他功能有关。下面来看看其他的构造函数

(2)拷贝构造:利用其他已初始化对象来初始化对象。

(3)从pos(下标)开始往后len长度的字符串来初始化对象,但这里可以看到len默认给了缺省值npos,从网站中可以看到npos的值是-1

但其实npos代表的是size_t类型的最大值,至于给-1的原因是size_t类型是unsigned类型,其最大值的二进制码全为1,而-1的补码就是全为1,因此就是最大值。

(4)利用C中的字符数组(包括常量字符数组)来初始化对象。

(5)取字符数组中前n个字符来初始化对象。

(6)初始化成n个c字符。

下面进行代码演示:

#include<iostream>
#include<string>using namespace std;//初始化
void Stringtest01()
{//(1)string s1;cout << s1 << endl;//(4)string s2("Hello World");cout << s2 << endl;//(5)string s3("Hello World", 2);cout << s3 << endl;//(2)string s4(s2);cout << s4 << endl;//(3)string s5_1(s2, 1);cout << s5_1 << endl; string s5_2(s2, 1, 6);cout << s5_2 << endl;string s6(5, 'a');cout << s6 << endl;
}int main()
{Stringtest01();return 0;
}

运行结果如下: 

2.2析构函数

主要用于释放对象中所申请的资源。

2.3赋值重载

赋值重载主要是为了完成给对象赋值操作:

(1)已初始化对象进行赋值。

(2)C字符串进行赋值。

(3)字符进行赋值

下面进行代码示例:

//赋值重载
void Stringtest02()
{string s1("abcdef");cout << s1 << endl;string s2;s2 = s1;cout << s2 << endl;string s3;s3 = "gh";cout << s3 << endl;string s4;s4 = 'i';cout << s4 << endl;
}int main()
{//Stringtest01();Stringtest02();return 0;
}

运行结果如下:

 3.迭代器

3.1初识迭代器

在C语言中对于字符数组的遍历,我们可以直接利用下标或者指针进行遍历,而STL中的容器成员变量可能会很复杂,或者不同容器的遍历逻辑不同,这时C++中引入了迭代器,来进行遍历。

3.2迭代器的使用

迭代器是每个STL容器中的内置类,对于string的迭代器使用如下:

//迭代器
void Stringtest03()
{string s1("1234567");//迭代器string::iterator it1 = s1.begin();while (it1 != s1.end()){cout << (*it1) << ' ';it1++;}cout << endl;
}int main()
{//Stringtest01();//Stringtest02();Stringtest03();return 0;
}

运行结果如下:

下面通过此代码来了解迭代器,首先来看看begin和end接口。

先看其返回可以知道begin是返回对象开始位置的迭代器指针,end则是最后元素的下一个位置的迭代器指针,可以看出迭代器是一种类指针用法。以string为例,begin可类比于返回字符数组的首元素指针,end则是返回'\0'位置的指针。以此从首元素地址遍历到最后元素地址。

begin和end接口为了区分const类型字符串,还重载了const类型接口,这里的详细使用在const迭代器位置讲。

其次,因为是类指针操作,所以对于非const对象,是能进行修改操作的:

//迭代器
void Stringtest03()
{string s1("1234567");//迭代器string::iterator it1 = s1.begin();cout << s1 << endl;while (it1 != s1.end()){--(*it1);it1++;}cout << s1 << endl;
}int main()
{//Stringtest01();//Stringtest02();Stringtest03();return 0;
}

运行结果如下

但要注意这里的解引用(*)迭代器指针运算符是重载的,仅对字符进行修改,其他成员变量不变。

3.3特殊迭代器

除了常用的普通迭代器,还有之前提到的const对象迭代器,以及逆序迭代器。

const迭代器主要为了进行const对象的遍历,string中也给出了对应的cbegin和cend接口(C++11标准):

而C++11之前则是使用的则是begin和end,const对象在迭代时便会自动调用const版本接口,而后的cbegin和cend是为了进行区分。

const迭代器类似于const char*的使用,不能对解引用内容进行修改,但可以修改指针变量的值。定义迭代器指针时使用的是const_iterator。

对于逆序迭代器(reverse_iterator)使用的则是rbegin与rend接口:

rbegin返回是最后一个元素的迭代器指针(不是'\0'),而rend返回的则是第一个元素之前元素的迭代器指针。

代码示例如下:

//迭代器
void Stringtest03()
{string s1("1234567");//迭代器string::iterator it1 = s1.begin();cout << s1 << endl;while (it1 != s1.end()){--(*it1);it1++;}cout << s1 << endl;//const迭代器const string s2("abcdef");string::const_iterator it2 = s2.begin();while (it2 != s2.end()){cout << *it2 << ' ';++it2;}cout << endl;//reverse迭代器string s3("ABCDEF");string::reverse_iterator rit3 = s3.rbegin();while (rit3 != s3.rend()){cout << *rit3 << ' ';++rit3;}cout << endl;
}int main()
{//Stringtest01();//Stringtest02();Stringtest03();return 0;
}

运行结果如下:

 除此之外reverse迭代器也有const版本,可以用C++11提出的crbegin和crend接口,也可用rbegin和rend的const重载版本。

3.4范围for

迭代器的使用语法相比python中的for循环相对繁琐,于是在C++11中引入了范围for来简化迭代器语法。

使用范围for前需要了解下auto关键字,auto实际是一种自动识别类型然后赋值的类型:

auto a = 'a';

 这里的范围for语法如下:

for(auto e : s1)
{cout << e << ' ';
}
cout << endl;

这里的范围for实际只是简化迭代器语法,但底层还是迭代器。 

4.大小接口

string的大小接口主要分为字符串长度相关接口和内部空间大小相关接口

4.1字符长度相关接口

string中长度相关接口主要有:字符串长度(size、length),最大字符串长度(max_size),再分配字符串长度(resize),清理字符(clear),判断是否为空串(empty),下面逐一了解

字符串长度(size、length)

对于size和length这两个接口返回的值是相同的,返回的都是真实的字符串长度(不包括'\0')。

清理字符串(clear)

清理字符串接口功能是将对象中的字符清空,使其变为空串,但内存空间不会进行改变。

字符串判空(empty)

字符串判空就是判断该对象是否为空字符,若为空字符串则返回true,非空则返回flase。

下面进行以上接口的代码演示:

//大小接口
void Stringtest04()
{string s1;cout << s1.size() << endl;cout << s1.length() << endl;s1 = "abcd";cout << s1.capacity() << endl;s1.clear();cout << s1.capacity() << endl;if (s1.empty()){cout << "string s1 is empty." << endl;}else{cout << "string s1 is not empty." << endl;}
}int main()
{//Stringtest01();//Stringtest02();//Stringtest03();Stringtest04();return 0;
}

这里的capacity接口是返回字符串字节大小(不包括'\0'),运行结果如下:

以上接口是常用的接口类型,剩下的接口不太常用,只进行说明,不进行代码演示。

最大字符长度(max_size)就是返回该对象成储存最大字符长度值,这里的最大值分配具体根据编译器来决定。

重置长度(resize)是将对象的长度重置成想要的长度大小,但不会小于真实字符串长度,具体能不能重置取决于编译器,因此不常用。

4.2空间大小相关接口

空间大小的接口包括:返回现有空间大小(capacity),预留空间(reserve),C++11中引入的缩容(shrink_to_fit),下面逐一介绍。

 对于之前提到的capacity接口,其只返回不包括结尾'\0'空间字节的空间大小,但实际的字符串空间是capacity() + 1。

reserve接口常用于扩容操作,比如对象需要储存很多字符,则可提前开辟相应大小空间,避免之后的多次扩容,但reserve不建议进行缩容操作,不仅效率低,编译器还不一定会进行。

对于缩容(shrink_to_fit)接口,其功能是缩容到相对于size合适空间,但不一定会缩到size,具体大小根据编译器来定

5.其他常用接口

 5.1operator[ ]

string中提供了像数组一样,通过[ ]和下标形式直接调用或修改字符串元素

 但这里的下标也是不能越界的,越界访问会进行assert断言:

//其他接口
void Stringtest05()
{string s1("abcdef");cout << s1[s1.size() + 1] << endl;
}int main()
{//Stringtest01();//Stringtest02();//Stringtest03();//Stringtest04();Stringtest05();return 0;
}

运行结果如下:

5.2增

string进行增加操作常用的是operate以及push_back()

但其中operate+=比push_back更常用,因为+=与尾插功能相似,但+=支持添加字符串,更为便捷。

//其他接口
void Stringtest05()
{string s1("abcdef");cout << s1[s1.size()] << endl;string s2;string s3;s2 += "123456";s3.push_back('1');s3.push_back('2');cout << s2 << endl;cout << s3 << endl;
}int main()
{//Stringtest01();//Stringtest02();//Stringtest03();//Stringtest04();Stringtest05();return 0;
}

 运行结果如下:

 5.3查

string中查的常用接口提供了find和rfind,find能从字符串中指定的pos位置开始向后查找字符c或字符串s,若找到则返回该位置的下标,若未找到则返回npos。

rfind与find功能相似,只不过rfind是从最后一个字符位置开始查找。 

代码演示:

//其他接口
void Stringtest05()
{string s1("abcdef");cout << s1[s1.size()] << endl;string s2;string s3;s2 += "123456";s3.push_back('1');s3.push_back('2');cout << s2 << endl;cout << s3 << endl;string s4 = "aaaaaa";cout << s4.find('a') << endl;cout << s4.rfind('a') << endl;cout << s4.find('b') << endl;
}int main()
{//Stringtest01();//Stringtest02();//Stringtest03();//Stringtest04();Stringtest05();return 0;
}

运行结果如下

5.4导出

导出接口中主要是为了提供string中特定串,常用的有提供C接口(c_str)和提供特点串(substr)。

c_str的提供主要是为了兼容C,因为C中的函数接口都是char*。

而substr可以将字符串中所需要的子串提取出来。

 其中长度问题:在左闭右开区间[a, b)中b - a就是a到b的长度,比如字符串"abc"的len就是s.size() - 0。

下面以提取网址中的协议、域名、目录为例,进行代码演示:

//分离网址
vector<string> split_url(const string& url)
{vector<string> v;size_t i1 = url.find(':');if (i1 != string::npos){v.push_back(url.substr(0, i1));}size_t i2 = i1 + 3;size_t i3 = url.find('/', i2);if (i3 != string::npos){v.push_back(url.substr(i2, i3 - i2));v.push_back(url.substr(i3 + 1));}return v;
}void test()
{string s1 = "https://gitee.com/xiao-chen-is-studying-c";vector<string> spurl = split_url(s1);cout << spurl[0] << endl;cout << spurl[1] << endl;cout << spurl[2] << endl;
}int main()
{//Stringtest01();//Stringtest02();//Stringtest03();//Stringtest04();//Stringtest05();test();return 0;
}

http://www.hkcw.cn/article/tqRwNPHAPF.shtml

相关文章

Android 代码阅读环境搭建:VSCODE + SSH + CLANGD(详细版)

在阅读Android源码&#xff08;AOSP超过1亿行代码&#xff09;时&#xff0c;开发者常面临索引失败、跳转卡顿等问题。本教程将手把手教你搭建基于VSCode SSH Clangd的终极阅读环境&#xff0c;实现秒级符号跳转、精准代码提示和高效远程开发。 一、环境架构解析 1.1 方案组…

JAVA 集合的进阶 泛型的继承和通配符

1 泛型通配符 可以对传递的类型进行限定 1.1 格式 ? 表示不确定的类型 &#xff1f;extends E&#xff1a; 表示可以传递 E 或者 E 所有的子类类型 &#xff1f;super E&#xff1a; 表示可以传递 E 或者 E 所有的父类类…

改写自己的浏览器插件工具 myChromeTools

1. 起因&#xff0c; 目的: 前面我写过&#xff0c; 自己的一个浏览器插件小工具 最近又增加一个小功能&#xff0c;可以自动滚动页面&#xff0c;尤其是对于那些瀑布流加载的网页。最新的代码都在这里 2. 先看效果 3. 过程: 代码 1, 模拟鼠标自然滚动 // 处理滚动控制逻辑…

由sigmod权重曲线存在锯齿的探索

深度学习的知识点&#xff0c;一般按照执行流程&#xff0c;有 网络层类型&#xff0c;归一化&#xff0c;激活函数&#xff0c;学习率&#xff0c;损失函数&#xff0c;优化器。如果是研究生上课学的应该系统一点&#xff0c;自学的话知识点一开始有点乱。 一、激活函数Sigmod…

仿腾讯会议——优化:多条tcp连接

1、添加用户信息结构 2、添加注册视频音频结构体 3、 完成函数注册视频音频

File—IO流

因为变量&#xff0c;数组&#xff0c;对象&#xff0c;集合这些数据容器都在内存中&#xff0c;一旦程序结束&#xff0c;或者断电&#xff0c;数据就丢失了。想要长久保存&#xff0c;就要存在文件中&#xff08;File&#xff09; 文件可以长久保存数据。 文件在电脑磁盘中…

【Zephyr 系列 2】用 Zephyr 玩转 Arduino UNO / MEGA,实现串口通信与 CLI 命令交互

🎯 本篇目标 在 Ubuntu 下将 Zephyr 运行在 Arduino UNO / MEGA 上 打通串口通信,实现通过串口发送命令与反馈 使用 Zephyr Shell 模块,实现 CLI 命令处理 🪧 为什么 Arduino + Zephyr? 虽然 Arduino 开发板通常用于简单的 C/C++ 开发,但 Zephyr 的支持范围远超 STM32…

最悉心的指导教程——阿里云创建ECS实例教程+Vue+Django前后端的服务器部署(通过宝塔面板)

各位看官老爷们&#xff0c;点击关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 阿里云创建ECS实例教程 注意&#xff1a; 阿里云有300元额度的免费适用期哟 白嫖~~~~ 注册了阿里云账户后&#x…

【Android】如何抓取 Android 设备的 UDP/TCP 数据包?

目录 前言理解抓包tcpdump 实时抓包Wireshark 解包抓包后的一些思考 前言 在真正接触 UDP/TCP 抓包之前&#xff0c;我一直以为这是一项高深莫测的技术。可当我们真正了解之后才发现&#xff0c;其实并没有那么复杂——不过如此。 所谓的大佬&#xff0c;往往只是掌握了你尚未…

VR看房系统,新生代看房新体验

VR看房系统的概念 虚拟现实&#xff08;VirtualReality,VR&#xff09;看房系统&#xff0c;是近年来随着科技进步在房地产行业中兴起的一种创新看房方式。看房系统利用先进的计算机技术模拟出一个三维环境&#xff0c;使用户能够身临其境地浏览和体验房源&#xff0c;无需亲自…

机器学习Day5-模型诊断

实现机器学习算法的技巧。当我们训练模型或使用模型时&#xff0c;发现预测误差很 大&#xff0c;可以考虑进行以下优化&#xff1a; &#xff08;1&#xff09;获取更多的训练样本 &#xff08;2&#xff09;使用更少的特征 &#xff08;3&#xff09;获取其他特征 &#xff…

STM32F103_Bootloader程序开发06 - IAP升级用的App.bin增加CRC32校验码,确保固件完整性,防止“变砖”

导言 《STM32F103_Bootloader程序开发05 - Keil修改生成文件的路径与文件名&#xff0c;自动生成bin格式文件》上一章节成功让Keil生成App.bin二进制文件&#xff0c;用于IAP升级。 为了保障IAP升级过程中的固件完整性&#xff0c;避免因损坏文件导致设备“变砖”&#xff0c;…

语言使用的国家概况统计

语言是文化的载体&#xff0c;也是沟通和协作的桥梁。随着全球化进程加快&#xff0c;了解主要语言的分布及其使用国家&#xff0c;对于数据分析师、产品经理、市场人员乃至技术开发者&#xff0c;都极为重要。本文将梳理全球几种主要语言&#xff08;英语、法语、阿拉伯语、俄…

DeepSeek-R1-0528

深度思考能力强化​ DeepSeek-R1-0528 仍然使用 2024 年 12 月所发布的 DeepSeek V3 Base 模型作为基座&#xff0c;但在后训练过程中投入了更多算力&#xff0c;显著提升了模型的思维深度与推理能力。 更新后的 R1 模型在数学、编程与通用逻辑等多个基准测评中取得了当前国内…

MCU STM32搭配存储SD NAND(贴片式T卡)于智能皮电手环(Galvanic Skin Response, GSR 手环)的全方位评测

文章目录 卓越性能强化安全高效能效图形处理优势丰富集成特性模拟模块实时监控保障数据完整性提升安全性与可靠性测量原理采样率相关 在智能皮电手环及数据存储技术不断迭代的当下&#xff0c;主控 MCU STM32H750 与存储 SD NAND MKDV4GIL-AST 的强强联合&#xff0c;正引领行业…

处理知识库文件_编写powershell脚本文件_批量转换其他格式文件到pdf文件---人工智能工作笔记0249

最近在做部门知识库&#xff0c;选用的dify&#xff0c;作为rag的工具&#xff0c;但是经过多个对比&#xff0c;最后发现&#xff0c; 比较好用的是&#xff0c;纳米搜索&#xff0c;但是可惜纳米搜索无法在内网使用&#xff0c;无法把知识库放到本地&#xff0c;导致 有信息…

Java 基础 常见知识

基本数据类型 Java 中基本数据类型&#xff1f;对应的包装类&#xff1f;占多少字节&#xff1f; Java 中有 8 种基本数据类型&#xff1a; 6 种数字类型&#xff1a; 4 种整数类型&#xff1a;byte、short、int、long2 种浮点类型&#xff1a;float、double 1 种字符类型&a…

直播预告 | 聚焦芯必达|打造可靠高效的国产 MCU 与智能 SBC 汽车解决方案

随着汽车电子国产化快速推进&#xff0c;车规级 MCU 与 CAN/LIN SBC 作为车身控制的核心组件&#xff0c;正面临更高的安全与可靠性挑战。品佳集团将携手芯必达微电子&#xff0c;深入剖析国产 MCU/SBC/智能 SBC 的最新技术与应用&#xff0c;助力企业打造高性能、可量产的国产…

TF 卡 U1 与 U3 的核心差异解析:从速度标准到应用场景

在选购 TF 卡时&#xff0c;常常会看到 U1、U3 等标识&#xff0c;这些标识代表着不同的性能等级。最近不少客户询问 TF 卡 U1 和 U3 的区别&#xff0c;接下来将从多个维度为您详细解读&#xff0c;并通过对比图表直观呈现差异。 对比项目U1U3速度标准最低写入速度 10MB/s最低…