C++-带你深度理解string类的常见接口

1. 为什么学习string类?

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

在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本 都使用string类,很少有人去使用C库中的字符串操作函数。


2. 标准库中的string

2.1 string(了解)

下面这个链接是c++官网里面有关string的文档介绍。

cplusplus.com/reference/string/string/?kw=string

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

string比STL出现的还要早,所以不包含在contain的类别里面,但也算是一种数据结构。

1. 字符串是表示字符序列的类
2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性。
3. string 类是使用 char( 即作为它的字符类型,使用它的默认 char_traits 和分配器类型 ( 关于模板的更多信息,请参阅basic_string)
4. string 类是 basic_string 模板类的一个实例,它使用 char 来实例化 basic_string 模板类,并用 char_traits和allocator 作为 basic_string 的默认参数 ( 根于更多的模板信息请参考 basic_string)
5. 注意,这个类独立于所使用的编码来处理字节 : 如果用来处理多字节或变长字符 ( UTF-8) 的序列,这个类的所有成员( 如长度或大小 ) 以及它的迭代器,将仍然按照字节 ( 而不是实际编码的字符 ) 来操作。
总结:
1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string。

4. 不能操作多字节或者变长字符的序列。 

使用 string 类时,必须包含 #include 头文件以及 using namespace std ;

2.2 string类的常用接口说明

2.2.1string的构造

 首先给大家介绍无参的string构造,以及使用字符串构造,还有拷贝构造这三种最常用的构造方式。如果想打印string类的对象直接使用cout即可,因为string类重载了流插入和流提取。

int main()
{
	//string(),构造空的string类对象s1
	string s1;
	//string(const char* s),用C格式字符串构造string类对象s2
	string s2("hello world");
	//string(string s),拷贝构造s3
	string s3(s2);
    cout<<s3<<endl;
	return 0;
}

 2.2.2string的析构

string相当于是一个管理字符串的顺序表,也就是字符串数组,内部的数组的是动态开辟的,需要释放,但是这个析构函数是自动调用的。

 

 2.2.3string的赋值重载

string类的赋值重载有三个,用的最多的还是前面两个。

int main()
{
	string s1("hello c++");
	string s2 = s1;
	string s3 = "hello c++";
	cout << s2 << endl;
	cout << s3 << endl;
	return 0;
}

 

2.2.4 string类对象的容量操作

2.2.4.1size和length

string类的size和length接口是完全一样的,只是由于STL的发展历史原因,后面才出现的size。虽说length出现的早,但是实际上size用的更多,都不包含/0。

2.2.4.2operator[]

那么我们怎么遍历一个string类的对象呢?使用[]是比较方便的,也更加容易理解,因为原始数组就是用的[]遍历的,[]就是operator[],运算符重载。 

int main()
{
	string s1 = "hello world";
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;
	return 0;
}

[]不仅可以读,也可以写,因为返回值是起始字符的引用。

int main()
{
	string s1 = "hello world";
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i];
	}
	cout << endl;
	s1[0] = 'z';
	cout << s1 << endl;
	return 0;
}

[]在字符串的遍历这方面也挺方便的,用起来跟数组的下标一样。

2.2.4.3c++的swap

c++的库里面有一个swap函数,用起来非常的方便,库里面的swap是一个函数模板,所以可以支持各种数据类型。

2.2.4.4迭代器

c++里面还有一个东西可以支持大部分数据类型的的遍历,那就是迭代器(iterator),迭代器不仅可以遍历,还可以修改,迭代器是主流的访问容器的一种方式。下标和[]适用于物理空间上是连续的情况,链式结构,树形结构,哈希表等就只能用迭代器来遍历。

注意:const_iterator是const迭代器,它的目的是使迭代器指向的内容不能被修改,而不是迭代器本身不能被修改。

2.2.4.5rbegin

如果我们想倒着访问string类的对象,可以使用反向迭代器reverse_iterator,rbegin指向最后一个字符,rend就是第一个字符,it++就是向前遍历。 

2.2.4.6reserve

 reserve就是保留的意思,可以给string预留空间,也就是开空间,在我们知道需要多少空间时,可以用reserve提前开好空间,reserve只影响容量,不会影响数据,当然各个编译器的机制不一样。

2.2.4.7capacity

capacity就是容量,代表的是实际能存放多少个字符,而不是实际空间有多大,因为最后还有\0,\0不算是有效字符,是个标识符,实际空间比capacity大一,因为要留个空间存放\0。 

int main()
{
	string s1 = "hello zxf";
	string::reverse_iterator it = s1.rbegin();
	while (it != s1.rend())
	{
		cout << *it;
		it++;
	}
	cout << endl;
	s1.reserve(30);
	cout << s1 << endl;
	cout << s1.capacity() << endl;
	return 0;
}

2.2.4.8resize

 大家再来看一下resize这个接口,resize既影响容量,也会影响数据,resize之后的容量肯定要比resize的数据要大,保证空间足够,size则为resize的大小,resize如果比之前的容量大,则会发生扩容,那么resize之后的数据既然是100了,那么当我们打印出来的时候,为什么什么都看不见呢?因为后面的数据全部都是\0。如果不想让后面是\0,就可以使用resize的一个重载,这个重载的第二个参数是一个字符。意思就是如果显示传了这个字符,那么后面插入的字符就是该字符,如果没有传的话,则是\0这个空字符。

在vs编译器上,如果resize的数据在size和capacity之间的话,那么size会发生变化,capacity不会变。

在vs编译器上,如果resize的数据小于size,那么size会减小,并且数据会删除,capacity不会变。

总结:

1.resize数据>capacity,扩容+尾插

2.size<resize数据<capacity,尾插

3.resize数据<size,尾删 

2.2.4.9push_back

push_back这个函数一次只能尾插一个字符,效率太低了,因此我们可以使用append。 

2.2.4.10append 

append函数有许多个重载,使用的方法也很简单,就不一一介绍了。

 

2.2.4.11operator+=

 虽然append实现了这么多重载,但是有一个接口更加好用,就是运算符+=的重载。+=不仅更加的方便,并且代码的可读性也变强了。 

 2.2.4.12insert

insert这个接口只要第一个和第三个重载用的最多,在某个位置插入字符串或者string类的对象。

 2.2.4.13erase

erase用法也很简单,不做过多说明。

 2.2.4.14assign

assign相当于赋值,也有许多个重载。

 2.2.4.15replace

replace就是替换的意思,虽然看起来很好用,但是成本比较高,不太推荐使用。

 2.2.4.16find

find就是查找某个字符,可以从任意位置开始查找,返回的是这个字符的下标,不给开始查找的位置则默认为0,如果找不到的话返回值是整型的最大值.

2.2.4.17copy

copy就是拷贝string类对象的一部分到一个数组里面去,下面这段代码就是从拷贝下标为4的位置开始拷贝,拷贝长度为6的字符。 

 

 2.2.4.18find_first_of

find_first_of就是在string类的对象里面找到需要找的字符,并且返回下标,注意寻找的可以是多个。

2.2.4.19find_last_of 

find_last_of就是从后往前找,用法和find_first_of是一样的。

2.2.4.20substr 

substr就是从pos位置开始读出长度为len的字符串,返回的是string类。

 


今天的分享到这里就结束了,感谢大家的阅读! 

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

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

相关文章

LeetCode周赛——384

1.修改矩阵&#xff08;模拟&#xff09; class Solution { public:vector<vector<int>> modifiedMatrix(vector<vector<int>>& matrix) {int n matrix.size();int m matrix[0].size();vector<int> ans(m);for(int i 0; i < m; i)for(…

如何写好一个简历

如何编写求职简历 论Java程序员求职中简历的重要性 好简历的作用 在求职过程中&#xff0c;一份好的简历是非常重要的&#xff0c;它甚至可以直接决定能否被面试官认可。一份出色或者说是成功的个人简历&#xff0c;最根本的作用是能让看这份简历的人产生一定要见你的强烈愿…

腾讯云4核8G服务器够用吗?来看看支持多少人访问!

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

基于 Python 的大数据的电信反诈骗系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【c语言】字符串常见函数 下

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;c语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&a…

文生图提示词:视角选择

构图和视角 --视角选择 Perspective Choices 涵盖从基本的摄影视角到更复杂和专业的视角技巧&#xff0c;展示了在视觉艺术创作中可以采用的多样化视角选择。 Eye Level 眼平线视角 High Angle 高角度 Low Angle 低角度 Birds Eye View 鸟瞰视角 Worms Eye View 虫视视角 Front…

【51单片机】直流电机驱动(PWM)(江科大)

1.直流电机介绍 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转 直流电机主要由永磁体(定子)、线圈(转子)和换向器组成 除直流电机外,常见的电机还有步进电机、舵机、无刷电机、空心杯电机等 2.电机驱动…

使用UMAP降维可视化RAG嵌入

大型语言模型&#xff08;LLMs&#xff09;如 GPT-4 已经展示了出色的文本理解和生成能力。但它们在处理领域特定信息方面面临挑战&#xff0c;比如当查询超出训练数据范围时&#xff0c;它们会产生错误的答案。LLMs 的推理过程也缺乏透明度&#xff0c;使用户难以理解达成结论…

Qt之条件变量QWaitCondition详解

QWaitCondition内部实现结构图&#xff1a; 相关系列文章 C之Pimpl惯用法 目录 1.简介 2.示例 2.1.全局配置 2.2.生产者Producer 2.3.消费者Consumer 2.4.测试例子 3.原理分析 3.1.辅助函数CreateEvent 3.2.辅助函数WaitForSingleObject 3.3.QWaitConditionEvent …

C++笔记1:操纵符输入输出

C操纵符用来控制输出控制&#xff0c;一是输出的形式&#xff0c;二是控制补白的数量和位置。本文记录一下&#xff0c;在一些笔试的ACM模式可能有用。其中1-4节的部分是关于格式化输入输出操作&#xff0c;5-6节的部分是关于未格式化输入输出操作。 1. 控制布尔值的格式 一般…

uniapp API文档地址 以及 HBuilder安装

uniapp API文档地址 以及 HBuilder安装 一、进入 当前网站 uni-app 官网 [uni-app](https://zh.uniapp.dcloud.io/quickstart-hx.html)二、点击截图下载文件 三、 进入 当前网站 &#xff08;https://www.dcloud.io/hbuilderx.html&#xff09; 浏览器会识别 也可以自行选择…

基于GIS、RS、VORS模型、CCDM模型、geodetecto、GWR模型集成的生态系统健康的耦合协调分析

详情点击公众号&#xff1a;技术科研吧 链接&#xff1a;基于GIS、RS、VORS模型、CCDM模型、geodetecto、GWR模型集成的生态系统健康的耦合协调分析 前沿 当空间大数据、云计算与人工智能发生碰撞,地理服务产业也不断发生变革与进步。ArcGIS Pro 是一个专业的桌面 GIS 应用程…

17 外排序

排序分为内排序和外排序&#xff0c;内排序是在内存中的排序。外排序指在磁盘中文件的排序&#xff0c;因为在磁盘中&#xff0c;不能进行下标访问&#xff0c;归并排序经常用于磁盘中文件的排序 假如有10亿个整形数据在磁盘中&#xff0c;要对它排序&#xff0c;内存中只有1G…

水果FL Studio21.2最新中文版功能特点介绍

FL Studio 21的特点和优势包括&#xff1a; 丰富的主题换肤&#xff1a;用户可以通过调整色调、饱和度、亮度、文本、仪表和步进序列器的颜色&#xff0c;来个性化定制FL Studio 21的外观&#xff0c;使其更符合个人审美或工作风格。更快的音频编辑&#xff1a;FL Studio 21集…

AI少女/HS2甜心选择2 仿剑三剑灵人物卡全合集打包

AI少女/HS2甜心选择2 仿剑三剑灵人物卡全合集打包 内含&#xff1a;菩提禅音[剑网3]明教晓天喵姐[剑3]明教晓天喵姐无帽版[剑3]茱莉亚[剑灵] 下载地址&#xff1a; https://www.changyouzuhao.cn/12492.html

软件价值12-射箭游戏

射箭游戏&#xff0c;按空格键发射&#xff0c;打击移动靶&#xff0c;左上角显示成绩状态。 代码&#xff1a; import pygame import sys import random# 初始化Pygame pygame.init()# 设置窗口大小 SCREEN_WIDTH 800 SCREEN_HEIGHT 600 screen pygame.display.set_mode((…

【开源】基于JAVA+Vue+SpringBoot的就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

DS:树及二叉树的相关概念

创作不易&#xff0c;兄弟们来波三连吧&#xff01;&#xff01; 一、树的概念及结构 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c…

利用Cloudflare Workers实现网页状态监控

首先 Fork cf-workers-status-page 浏览器地址栏输入 https://deploy.workers.cloudflare.com/?urlhttps://github.com/$YourUserName/cf-workers-status-page 获取 Cloudflare 账户内的 Account ID 和 API Token 授权的 token 需要 workes 的编辑权限 在 Github actio…

LeetCode二叉树的垂序遍历

题目描述 给你二叉树的根结点 root &#xff0c;请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言&#xff0c;其左右子结点分别位于 (row 1, col - 1) 和 (row 1, col 1) 。树的根结点位于 (0, 0) 。 二叉树的 垂序遍历 从最左边的列开始直到…