C++ STL-string 类使用超详解

目录

0. 引言

1. string 类

1.1 string类的基本概念

1.2 string类与char*的区别

1.3 string类的作用 

 2. string 的接口使用

2.1  string 类对象的默认成员函数

2.1.1 构造函数 - 初始化

 2.1.2 npos 含义

2.2 赋值重载 - 初始化

 2.3 析构函数

 2.2 string 类对象的访问和遍历操作

2.2.1  operator[ ] 

2.2.2 at

2.2.3 迭代器 

2.2.4 范围 for  

2.3  string 常见的容量操作

 2.3.1 size 和 length​编辑​编辑

2.3.2 capacity 

2.3.3 empty ​编辑

2.3.4 reserve ​编辑

2.3.4 resize ​编辑

2.4 string 常见修改操作 

2.4.1 operator +=

2.4.2 insert 

2.4.3 erase ​编辑

2.5 string其他操作 


0. 引言

STL(standard template libaray-标准模板库)是C++的一个重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。因此,学习和使用STL显得格外的重要。

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

1. string 类

1.1 string类的基本概念

string 就是字符串的意思,是 C++用来代替char数组的数据结构。里面封装了一些常用的方法,方便我们地对其进行一些操作,而且string的空间大小是动态变化的,大大减小了不必要的花销 。

1.2 string类与char*的区别

(1) char* 是一个指针

(2) string 本质上是一个类,类的内部封装了char*,即 string 是一个 char* 型的容器

(3) string 管理所分配的 char* 内存,不用担心复制越界和取值越界等

 C++ string 类它提供了一系列成员函数和操作符,使得字符串的操作更加方便和灵活。 

1.3 string类的作用 

string类 它可以存储任意数目的字符。它可以用来表示文本或其他字符串数据,例如:文本文件内容、网络传输的数据、数据库中的文本列、用户输入或输出等。

string 类的作用有以下几个方面:string类可以存储和操作任意数目的字符,可以处理文本数据,如搜索、替换、截取子串等操作。使用string类可以方便地进行字符串操作。 如连接(concatenate)两个字符串、删除(erase)字符串中的一些字符、复制(copy)字符串等。string类是C++标准库的一部分,可用于在不同的计算机和操作系统之间进行可靠的代码交换。

 2. string 的接口使用

2.1  string 类对象的默认成员函数

函数名称功能
constructor构造函数
destructor析构函数
operator=赋值重载
2.1.1 构造函数 - 初始化

红色框出来的是重点,下面的代码我们做出了一些说明:

string();		// 构造一个空字符串
string (const char* s);				// 用C-string来构造string类对象
string (const char* s, size_t n);	// 用C-string的前n个字符来构造string类对象
string (size_t n, char c);		// 生成n个c字符的字符串
 
string (const string& str);		// 利用原先的字符串做拷贝构造
// 拷贝str字符串中从pos位置开始的len个字符
string (const string& str, size_t pos, size_t len = npos);

照着说明,我们可以做出如下的验证: 

我们看到了这句代码: string (const string& str, size_t pos, size_t len = npos); 

 其中为什么结尾给 npos 呢?npos 代表什么,我们接下来看一下。

 2.1.2 npos 含义

Maximum value for size_t 说明了其为无符号整数的最大值,我们将其打印发现:

这是一个非常大的值,编译器默认就是从当前的这个【pos】位置开始一直到字符串末尾,这就是npos的作用。 也就是说 npos则直接到达字符串的末尾。

2.2 赋值重载 - 初始化

 下面的代码是我们做出了一些说明:

string& operator= (const string& str);	// 将一个string对象赋值给到另一个
string& operator= (const char* s);		// 将一个字符串赋值给到string对象
string& operator= (char c);				// 将一个字符赋值给到string对象

照着说明,我们同样可以做出如下的验证:  

 2.3 析构函数

 2.2 string 类对象的访问和遍历操作

接口说明
operator[ ]返回pos位置的字符,const string类对象调用
at()返回pos位置的字符,const string类对象调用
迭代器begin() end() / rbegin()  rend()
范围for范围for遍历
2.2.1  operator[ ] 

看到 [ ] 我们肯定能够想到运算符重载。operator [ ] 具有两个重载函数,一个是普通对象,一个则是const对象。

因此我们可以根据 operator[ ] 就可以利用 下标+ [ ] 来访问string中任何一个元素了。例如:

我们知道,sting 类的对象中的字符是存储在堆上面的,那是否和C语言相同以'\0'结尾呢?我们调试来看:string封装很多,不过仍然能看到结尾的 '\0' 。

同时我们也可以利用 下标+ [ ] 对字符来进行更改:

因此,opterator [ ] 可以让我们对字符串的使用类似于数组的增删查改。 

2.2.2 at

 我们可以看到 at 同样具有两个重载函数,一个是普通对象,一个则是const对象。

2.2.3 迭代器 
接口说明
begin()返回指向第一个元素的迭代器
end()返回指向最后一个元素的下一个位置的迭代器
rbegin()返回指向最后一个元素的反向迭代器
rend()返回指向第一个元素的前一个位置的反向迭代器

迭代器是是另一种访问string中内容的方式,图示如下,我们使用一个 it 去保存这个字符串begin处的位置,那么在其不断进行后移的过程中,就是在遍历这个字符串,当其到达最后的 end 处时,也就遍历完了。反向迭代器则方向相反,过程如图所示:

参考代码如下:

string s1("hello world");
cout << s1 << endl;
cout << "正向迭代器:";
string::iterator it = s1.begin();
while (it != s1.end())
{
	cout << *it << " ";
	it++;
}
cout << endl;

cout << "反向迭代器:";
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{
	cout << *rit << " ";
	rit++;
}
cout << endl;

 迭代器的这种方式,其实和指针非常得类似,其中 iterator 是像指针但不是指针。

2.2.4 范围 for  

范围 for 就是我们上次提到过的 语法糖

需要注意的是,范围for的底层实现还是【迭代器】,它在遍历的时候相当于是将 *it 的数据给到当前的ch,和迭代器的本质还是一样的。

2.3  string 常见的容量操作

接口说明
size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty检测字符串是否为空串,是返回true,否返回false
reverse为字符串预留空间
resize将有效字符串的个数改成 n 个,多出的空间用字符c填充
 2.3.1 size 和 length

我们发现size 和 length 定义是一模一样的,都是返回字符串的长度。 结果也是一模一样的。

2.3.2 capacity 

capacity() 表示为字符串开辟的空间大小。 

下面我们来看一下 windows 平台下是如何动态扩容的:

string s;
size_t sz = s.capacity();
cout << "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
	s.push_back('L');
	if (sz != s.capacity())
	{
		sz = s.capacity();
		cout << "capacity changed: " << sz << '\n';
	}
}

Windows下的VS中,扩容以1.5倍大小扩容。

2.3.3 empty 

检测字符串是否为空串,是返回true,否返回false 。

2.3.4 reserve 

 reserve 可以提前为字符串开辟一个大小为 n 的 空间。

因此 reserve 可以为我们提前开好所需的空间。 

2.3.4 resize 

上面说到 reserve 只是扩容,而 resize 是初始化字符串的个数。  另外使用resize时,size和capacity都会改变,并且二者的capacity 比给出的参数 n 还会大一点。 

因此当 n > 当前的字符串长度,resize 在末尾插入所需数量的字符以达到n的大小来扩展当前内容 

那么,当  n < 当前的字符串长度会发生什么呢?

n < 当前的字符串长度时,则会去进行一个删除的操作,删除第n个字符之后的字符 。

2.4 string 常见修改操作 

接口说明
push_back在字符串后尾插字符
append在字符串后面追加一个字符串
operator+=在字符产后面追加字符串str
insert在指定位置插入字符或字符串
assert使用指定的字符串替换原字符串
erase删除字符串中的一部分
replace替换指定区间的字符串
pop_back删除字符串的最后一个字符串
swap收缩到合适大小

这里我们对 operator+=() , insert(), erase 进行详细解释。

2.4.1 operator +=

+= 是运算符重载,一共有三个重载形式,分别是拼接一个string类的对象、一个字符串、一个字符 。

可以看出+=十分方便,可以代替push_back, append 的使用。

2.4.2 insert 

insert 函数重载形式很多: 

说明如下:

// 在指定位置插入一个string对象
string& insert (size_t pos, const string& str);
// 在指定位置插入一个string对象里的一部分
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
// 在指定位置插入一个字符串
string& insert (size_t pos, const char* s);
// 在指定位置插入一个字符串的前n个字符
string& insert (size_t pos, const char* s, size_t n);
// 在指定位置插入n个字符
string& insert (size_t pos, size_t n, char c);
// 在指定迭代器的位置插入n个字符
void insert (iterator p, size_t n, char c);
// 在指定迭代器的位置插入一个字符,并且返回一个迭代器的位置
iterator insert (iterator p, char c);

例如我们可以做出如下的使用:

2.4.3 erase 

例如: 

2.5 string其他操作 

此外还有一些其他比较重要的操作,在这里我们将其详细的列出来:

接口说明
c_str返回 C语言格式字符串
substr在str中从pos位置开始往,截取n个字符,然后将其返回
find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
find_frist_of从前往后找第一个匹配的字符
find_last_of从后往前找第一个匹配的字符
find_first_not_of从前往后找第一个不匹配的字符
find_last_not_of从后往前找第一个不匹配的字符
operator+()尽量少用,因为传值返回,导致深拷贝效率低
relational operator大小比较
operator>>()流插入重载
operator<<()流提取重载
getline获取一行字符串

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

目前服务器2核4G支持多少人同时访问?性能如何?

腾讯云轻量应用服务器2核4G5M配置性能测评&#xff0c;腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;并发数10&#xff0c;支持每天5000IP人数访问&#xff0c;腾讯云百科txybk.com整理2核4G服务器支持多少人同时在线&#xff1f;并发数测试、CPU性能、内存性能、…

Qt 窗口MainWindow(下)

对话框 对话框是 GUI 程序中不可或缺的组成部分。一些不适合在主窗口实现的功能组件可以设置在对话框中。对话框通常是一个顶层窗口&#xff0c;出现在程序最上层&#xff0c;用于实现短期任务或者简洁的用户交互。Qt 常用的内置对话框有: QFiledialog (文件对话框)、QColorDi…

36.基于SpringBoot + Vue实现的前后端分离-高校汉服租赁网站系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的高校汉服租赁网站系统设计与实现管理…

【包远程安装运行】SpringBoot+Mysql实现的美食分享菜谱制作平台+演示视频+开发文档(论文模板)

今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的美食分享菜谱制作平台系统&#xff0c;该系统分为前台和后台&#xff0c;多用户分享平台。主要实现了 除脚手架功能以外下面是系统的功能&#xff1a; 前台普通用户&#xff1a;注册、登录、首页、美食…

如何在软件测试行业走的更远?

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 时间往前推10年&#xff0c;IT业如日中天。 其中测试更是一个极具包容性的行业。那些希望在技术…

图像抠图DIS——自然图像中高精度二分图像抠图的方法(C++/python模型推理)

概述 DIS&#xff08;Dichotomous Image Segmentation&#xff09;是一种新的图像分割任务&#xff0c;旨在从自然图像中分割出高精度的物体。与传统的图像分割任务相比&#xff0c;DIS更侧重于具有单个或几个目标的图像&#xff0c;因此可以提供更丰富准确的细节。 为了研究…

Java只有中国人在搞了吗?

还是看你将来想干啥。想干应用架构&#xff0c;与Java狗谈笑风生&#xff0c;沆瀣一气&#xff0c;你就好好写Java&#xff0c;学DDD&#xff0c;看Clean Architecture。你想成为炼丹玄学工程师&#xff0c;年入百万&#xff0c;就选python&#xff0c;专精各种paper。你不在意…

如何修改SystemUI Clock的样式

开机的流程为&#xff1a; 在 CollapsedStatusBarFragment 的onCreateView 方法中 inflate R.layout.status_bar.xml&#xff0c; 里面定义有Clock。 CollapsedStatusBarFragment 的被调用流程为&#xff1a; 在StatusBar 的makeStatusBarView方法中显示出来。 所以可以在文…

Vue 若依框架 form-generator添加表格组件和动态表单组件

效果图&#xff1a; 在若依框架自带的流程表单配置基础上添加这两个组件 config.js // 表单属性【右面板】 export const formConf {formRef: elForm,formModel: formData,other: other,size: medium,labelPosition: right,labelWidth: 100,formRules: rules,gutter: 15,dis…

vue2 和 vue3 配置路由有什么区别

vue2 和 vue3 配置路由有什么区别 初始化路由器实例&#xff1a;注入到应用中&#xff1a;动态路由参数和捕获所有路由&#xff1a;编程式导航 API&#xff1a;异步加载组件&#xff1a; vue2 如何 使用路由 第一步&#xff1a;安装 vue-router第二步&#xff1a;创建路由组件第…

在面对API的安全风险,WAAP全站防护能做到哪些?

随着数字化转型的加速&#xff0c;API&#xff08;应用程序接口&#xff09;已经成为企业间和企业内部系统交互的核心组件。在应用程序开发过程中&#xff0c;API能够在不引起用户注意的情况下&#xff0c;无缝、流畅地完成各种任务。例如从一个应用程序中提取所需数据并传递给…

【MySQL】知识点 + 1

# &#xff08;1&#xff09;查询当前日期、当前时间以及到2022年1月1日还有多少天&#xff0c;然后通过mysql命令执行命令。 select curdate() AS 当前日期,curtime() AS 当前时间,datediff(2022-01-01, curdate()) AS 距离2022年1月1日还有天数;# &#xff08;2&#xff09;利…

【iOS ARKit】3D文字

首先&#xff0c;3D场景中渲染的任何虚拟元素都必须具有网格&#xff08;顶点及顶点间的拓扑关系&#xff09;&#xff0c;没有网格的元素无法利用GPU 进行渲染&#xff0c;因此&#xff0c;在3D 场景申渲染 3D文字时&#xff0c;文字也必须具有网格。在计算机系统中&#xff0…

发展新质生产力,亚信科技切中产业痛点

管理学大师拉姆查兰认为&#xff0c;经营性不确定性通常在预知范围之内&#xff0c;不会对原有格局产生根本性影响&#xff1b;而结构性不确定性则源于外部环境的根本性变化&#xff0c;将彻底改变产业格局&#xff0c;带来根本性影响。 毫无疑问&#xff0c;一个充满结构性不…

VS Code配置Python环境

首先贴一张完全卸载VS Code的图&#xff0c;包括一些配置和插件。 讲述一下如何配置Python环境以及和Conda的配合使用(涉及到虚拟环境) VS Code配置Python需要三步&#xff1a;安装Python环境&#xff1b;在VS Code软件中下载Python插件&#xff1b;新建python文件开始coding。…

Docker容器初始

华子目录 docker简介虚拟化技术硬件级虚拟化硬件级虚拟化历史操作系统虚拟化历史基于服务的云计算模式 什么是dockerDocker和传统虚拟化方式的不同之处为什么要使用docker&#xff1f;Docker 在如下几个方面具有较大的优势 对比传统虚拟机总结docker应用场景docker改变了什么 基…

抖音小店和抖音橱窗有什么区别?普通人最适合做哪个?

大家好&#xff0c;我是电商糖果 说起抖音卖货&#xff0c;很多人都会搞不清楚抖音小店和抖音橱窗有什么不同。 甚至有的朋友将他们认为是一个项目。 这里糖果就帮大家仔细的分辨一下&#xff0c;想在抖音卖货的普通人&#xff0c;看看它们谁最适合自己。 来百度APP畅享高清…

MySQL中的基本SQL语句

文章目录 MySQL中的基本SQL语句查看操作创建与删除数据库和表修改表格数据库用户管理 MySQL中的基本SQL语句 查看操作 1. 查看有哪些数据库 show databases; 2.切换数据库 use 数据库名;比如切换至 mysql数据库 use mysql;3.查看数据库中的表 show tables;4.查看表中…

干货分享 | TSMaster如何同时记录标定变量和DBC信号至BLF文件

客户在使用TSMaster软件标定功能时&#xff0c;有如下使用场景&#xff1a;将DBC文件中的信号与A2L文件中的标定变量同时记录在一个记录文件。针对此应用场景&#xff0c;TSMaster软件提供了一种方法来满足此需求。今天重点和大家分享一下关于TSMaster软件中同时记录标定变量和…

【计算机组成】计算机组成与结构(四)

上一篇&#xff1a;【计算机组成】计算机组成与结构&#xff08;三&#xff09; &#xff08;7&#xff09;存储系统 计算机采用分级存储体系的主要目的是为了解决存储容量、成本和速度之间的矛盾问题。 两级存储:cache-主存、主存-辅存(虚拟存储体系) 局部性原理 ◆ 局部性…