Cpp::STL—string类的使用与理解(下)(9)

news2024/11/18 15:50:27

文章目录

  • 前言
  • 一、string类对象的修改
    • operator+= (重点)
    • assign
    • insert
    • erase
    • replace
    • c_str
  • 二、string类对象的查找
    • find
    • rfind
    • substr
  • 三、string类非成员函数
    • operator+
    • relational operator
    • getline
  • 四、VS和g++下string结构说明
    • vs下string的结构
    • g++下string结构
  • 总结


前言

  我认为要想详尽认识string,请看该文档
  接上篇,我们继续来学习string这个类吧
  正文开始!


一、string类对象的修改

在这里插入图片描述

函数名称功能说明
operator+= (重点)在字符串后追加字符串或字符
append在字符串后拼接
push_back在字符串后尾插字符c
assign(奇葩)将空间中数据清空再添加所需内容
insert从某个位置开始插入字符
erase从某个位置开始删除len个字符
replace在字符串中某个区间位置的字符进行字符替换
pop_back尾删一个字符

operator+= (重点)

在这里插入图片描述
这个重载真的给了很大的自由度!,做到了让字符串可以加字符串、C字符串甚至是一个字符

在这里插入图片描述

所以,你会发现push_back()和append()没什么必要学习,至少我是真的懒得学这两个,如果真有需要,那看文档也是很方便的事

assign

功能:将空间中数据清空再添加所需内容,就是赋值的意思,如果出现空间不足问题,会自动扩容满足当前空间需求

int main()
{
	string str1("hello world");
	str1.assign("xxx");

	cout << str1 << endl; // xxx

	return 0;
}

记一下吧,虽然我目前还没遇到过具体实用场景

insert

功能:从字符串的某个位置开始插入

我们不妨来看下它的三个还算能用到的重载
string& insert (size_t pos, const string& str);
string& insert (size_t pos, const char* s);
iterator insert (iterator p, char c);

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s("C"); // C

	// insert(pos, str)在pos位置插入字符串str
	s.insert(1, "S"); // CS

	// insert(pos, string)在pos位置插入string对象
	string t("D");
	s.insert(2, t); // CSD

	// insert(pos, char)在pos位置插入字符char
	s.insert(s.end(), 'N'); // CSDN
	
	cout << s << endl; // CSDN
	return 0;
}

erase

功能:从字符串的某个位置开始删除
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s("I like C++!!!");

	// erase(pos, n) 删除 pos 位置开始的 n 个字符
	s.erase(8, 5); // I like C

	// erase(pos) 删除 pos 位置的字符
	s.erase(s.end()-1); // I like

	// erase(pos1, pos2) 删除 [pos1pos2) 上所有字符
	s.erase(s.begin() + 1, s.end()); // I

	cout << s << endl; // I
	return 0;
}

replace

功能:在字符串中某个区间位置的字符进行字符替换
在这里插入图片描述

我们来注意这两个重载:
string& replace (size_t pos, size_t len, const char* s);
string& replace (size_t pos, size_t len, size_t n, char c);

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s("hello world");

	// replace(pos, len, str)将pos位置开始的len个字符替换为字符串str
	s.replace(6, 4, "CSDN"); // hello CSDNd

	// replace(pos, len, n, char)将pos位置开始的len个字符替换为n个字符char
	s.replace(10, 1, 3, '!'); // hello CSDN!!!
	cout << s << endl;
	
	return 0;
}

对于insert、erase、replace来说,底层逻辑是挪动数据,时间复杂度很高,效率很低,能不使用就不使用,建议多使用operator+=

c_str

功能:返回C格式字符串(包括’\0‘)
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s("hello world ");

	const char* str = s.c_str();
	cout << str << endl; // hello world 

	return 0;
}

二、string类对象的查找

find

功能:如果找到相对应的字符或字符串后,find会返回该字符或字符串首位所在的索引位置(从0开始的下标索引位置),如果没有匹配成功,find则会返回npos(-1)
在这里插入图片描述

同样,我们观察这三个重载即可:
size_t find(const string& str, size_t pos = 0) const;
size_t find(const char* s, size_t pos = 0) const
size_t find(char c,size_t pos = 0) const

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	// find(string)正向搜索与string对象所匹配的第一个位置
	string s2("www");
	size_t pos1 = s1.find(s2);
	cout << pos1 << endl; // 7

	// find(str)正向搜索与字符串str所匹配的第一个位置
	char str[] = "cplusplus.com";
	size_t pos2 = s1.find(str);
	cout << pos2 << endl;  // 11

	// find(char)正向搜索与字符char所匹配的第一个位置
	size_t pos3 = s1.find(':');
	cout << pos3 << endl; // 4
	
	return 0;
}

rfind

功能:如果找到相对应的字符或字符串后,rfind会返回该字符或者返回该字符串最后一个字符所在的索引位置;如果没有匹配成功,rfind则会返回npos(-1)
在这里插入图片描述

size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;
size_t rfind (char c, size_t pos = npos) const;

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	// rfind(string)反向搜索与string对象所匹配的第一个位置
	string s2("string");
	size_t pos1 = s1.rfind(s2);
	cout << pos1 << endl; //42

	// rfind(str)反向搜索与字符串str所匹配的第一个位置
	char str[] = "reference";
	size_t pos2 = s1.rfind(str);
	cout << pos2 << endl;  //25

	// rfind(char)反向搜索与字符char所匹配的第一个位置
	size_t pos3 = s1.rfind('/');
	cout << pos3 << endl; //53
	
	return 0;
}

substr

功能:在str中pos位置开始,截取n个字符,然后将其返回
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1("abcdef");
	string s2;

	// substr(pos, n)提取pos位置开始的n个字符序列作为返回值
	s2 = s1.substr(2, 4);
	cout << s2 << endl; // cdef
	
	return 0;
}

三、string类非成员函数

  接下来介绍以下函数不属于string类中函数,而是属于全局函数。如果需要使用需要使用对应的头文件
在这里插入图片描述

operator+

在这里插入图片描述
  一样冗余的令人忍俊不禁,const char* s 能被隐式类型转换为 const string s,但一想可能早期CPU性能不行,于是很多情况下我们还是写了两种可能,这确实有一定的积极意义,其实可以想象当时编写string类的人的矛盾与纠结,但最后还是把不同的情况都给了出来,这可以看出来C++追求运行效率性能的决心

relational operator

在这里插入图片描述
  比较大小,注意我们比较的是字典序

getline

字符串里面最后一个单词的长度
我们不妨先来看这一道编程题
在这里插入图片描述
你可能感觉很简单,流插入一下str,并且反向查找空格字符

但是你会发现这样通过不了,如果你用的是cin >> str的话,原因在于读取字符串遇到空格或者换行符会终止问题,于是这里getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止

另一种重载可以支持我们自行设定分隔符
istream& getline (istream& is, string& str, char delim);

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s;
	getline(cin, s, 'D'); // 输入:hello CSDN
	cout << s << endl; // 输出:hello CS
	
	return 0;
}

四、VS和g++下string结构说明

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节,有些内容暂时看不懂没关系,后期有个更全面的掌握再回头看也不迟,只是你要有个不同平台下string类的实现有很大的不同这个认识即可

vs下string的结构

  string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:

  1. 当字符串长度小于16时,使用内部固定的字符数组来存放
  2. 当字符串长度大于等于16时,从堆上开辟空间
union _Bxty
{ 	// storage for small buffer or pointer to larger one
	value_type _Buf[_BUF_SIZE];
	pointer _Ptr;
	char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

  这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。
  其次还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量,还有一个指针做一些其他事情

故总共占16+4+4+4=28个字节

在这里插入图片描述

g++下string结构

  G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间

struct _Rep_base
{
    size_type _M_length;
    size_type _M_capacity;
    _Atomic_word _M_refcount;
};

总结

  使用 std::string 可以显著提高代码的安全性、可读性和可维护性,同时减少了手动内存管理带来的复杂性和风险。在现代 C++ 编程中,std::string 已成为处理字符串的首选工具,除非在特定情况下(如需要与 C 代码库兼容)才会选择使用 C-string
  马上就要来学习string类的底层实现了,期待吧!

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

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

相关文章

Json 在线可视化工具,分享几个

文章目录 1.json.cn2.json4u.cn3.jsonvisual.com4.jsoncrack5.altearius.github.io6.json.wanvb.com 前序&#xff1a;本文是对多种 Json 在线可视化工具 的介绍、分享。Json官网 https://www.json.org/json-en.html 个人比较中意第四款&#xff1a; https://jsoncrack.com/ed…

数据仓库简介(一)

数据仓库概述 1. 什么是数据仓库&#xff1f; 数据仓库&#xff08;Data Warehouse&#xff0c;简称 DW&#xff09;是由 Bill Inmon 于 1990 年提出的一种用于数据分析和挖掘的系统。它的主要目标是通过分析和挖掘数据&#xff0c;为不同层级的决策提供支持&#xff0c;构成…

Vector不清晰点学习易错点

什么是迭代器 是一个广义指针它可以是指针&#xff0c;也可以是一个可对其执行类似指针得操作-如解除引用&#xff08;如operator*()&#xff09;和递增&#xff08;operator()&#xff09;STL中每个容器类都定义了一个合适的迭代器&#xff0c;该迭代器的类型是一个名为itera…

解决iPhone无法有效响应问题的指南

当您触摸、滑动和点击屏幕时&#xff0c;iPhone 没有响应或屏幕冻结是很烦人的。不可否认&#xff0c;iPhone 是最好的智能手机之一&#xff0c;但它并不完美。触摸屏冻结是 iPhone 用户面临的最常见问题之一。 好消息是&#xff0c;这个问题通常是由软件错误而不是硬件损坏引…

每日学习一个数据结构-DAG有向无环图

文章目录 有向无环图的特性使用场景 有向无环图&#xff08;Directed Acyclic Graph&#xff0c;简称DAG&#xff09; 是一种特殊的图结构&#xff0c;在数学和计算机科学领域有广泛应用。它由顶点&#xff08;vertices&#xff09;和边&#xff08;edges&#xff09;组成&…

C# Windows EventHandler事件的使用

在实现项目中有这样一个使用场景&#xff0c;在一个独立的类库中&#xff0c;它没有对其他类库的引用。所以它能调用的资源有限。这时想在这个类库的一个窗体中的一个按钮要实现一个功能时就会发现有很多要调用的资源没有&#xff0c;无法实现业务逻辑。这时怎么办&#xff1f;…

如何设置一个拉风的PowerShell命令永久别名?

大家好啊&#xff0c;我是豆小匠。 这期来介绍下怎么在PowerShell中设置自己的命令别名。类似Linux系统的alias&#xff01; 1、设置永久别名 设置永久别名需要把命令写入到Microsoft.PowerShell_profile.ps1文件中&#xff08;ps1就是PowerShell脚本文件的扩展名&#xff09…

华为LTC流程架构分享

文末附LTC流程管理PPT下载链接~ 前面笔者分享了华为LTC流程相关PPT&#xff0c;应读者需求&#xff0c;今天从架构角度进行再次与读者共同学习下LTC流程架构。 华为LTC流程架构是一个全面且集成的业务流程体系&#xff0c;从线索发现开始&#xff0c;直至收回现金&#xff0c…

MySQL基础--表的增删改查

目录 一、前言二、新增&#xff08;Create)2.1 单行数据全列插入2.2 单行数据全列插入&#xff08;简写&#xff09;2.3 指定列插入2.4 多行插入 三、查询3.1 全列查询3.2 指定列查询3.3 查询的结果是一个表达式3.3.1 把所有的语文成绩在原本的基础上加一分3.3.2 列与列之间的计…

Docker精讲:基本安装,简单命令及核心概念

docker服务部署 docker是一个容器管理工具&#xff0c;其内部容器才是具体服务&#xff0c;所以我们在安装docker时不需要有太多定制内容&#xff0c;只需要通过yum安装即可 1. 更新系统包 #更新现有依赖包&#xff0c;防止现有依赖包版本过低影响docker安装 yum update2. 安…

【Python】FeinCMS:轻量级且可扩展的Django内容管理系统

在互联网飞速发展的今天&#xff0c;内容管理系统&#xff08;CMS&#xff09;成为了网站开发中的核心工具&#xff0c;尤其对于需要频繁更新内容的企业和个人站点而言&#xff0c;CMS 提供了极大的便利。市场上有许多不同的 CMS 工具可供选择&#xff0c;其中基于 Django 框架…

游戏如何对抗改包

游戏改包是指通过逆向分析手段及修改工具&#xff0c;来篡改游戏包内正常的设定和规则的行为&#xff0c;游戏包被篡改后&#xff0c;会被植入/剔除模块进行重打包。 本期图文我们将通过实际案例分析游戏改包的原理&#xff0c;并分享游戏如何应对改包问题。 安卓平台常见的改…

Arch - 架构安全性_保密(Confidentiality)

文章目录 OverView导图保密保密强度与成本客户端加密密码存储与验证 Code总结 OverView 即使只限定在“软件架构设计”这个语境下&#xff0c;系统安全仍然是一个很大的话题。 接下来我们将对系统安全架构的各个方面进行详细分析&#xff0c;包括认证、授权、凭证、保密、传输…

三菱PLC数据 转 profinet IO项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 网关采集三菱PLC数据 2 5 用PROFINET IO协议转发数据 5 6 其他说明 8 7 案例总结 9 1 案例说明 设置vfbox网关采集三菱PLC数据把采集的数据转成profinet IO协议转发给其他系统。 2 VFBOX网关工作原理 VFBOX网关是协…

探索光耦:光耦在电脑电源中的应用及其重要性

随着计算机技术的飞速发展&#xff0c;电脑已成为现代生活和工作中不可或缺的工具。无论是日常办公、游戏娱乐还是复杂的图像处理&#xff0c;电脑电源的稳定性和安全性都至关重要。作为电脑电源的核心部件之一&#xff0c;光耦&#xff08;光电耦合器&#xff09;在提升电源性…

智慧场馆智能化设计方案

1. 智慧场馆智能化规划设计方案 本方案针对智慧场馆的智能化系统进行综合设计&#xff0c;包括入侵报警、视频监控、门禁管理、公共广播等子系统&#xff0c;旨在实现智慧、安全、节能的现代化场馆。 2. 系统设计范围 设计内容广泛&#xff0c;覆盖了从安全监控到环6境监测&…

【期刊】论文索引库-SCI\SSCI\IE\南大核心\北大核心\CSCD等

外文期刊检索 SCI SCI即《科学引文索引》(Science Citation Index),是由美国科学信息研究所(Institute for Scientific Information)创建于1961年,收录文献的作者、题目、源期刊、摘要、关键词,不仅可以从文献引证的角度评估文章的学术价值,还可以迅速方便地组建研究课…

基于php的律所管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Tomcat安装和配置教程(图文详解,最简洁易懂)

本教程主要分为两个部分&#xff1a;Tomcat的下载和安装、Tomcat的配置 前提 Tomcat都需要Java环境&#xff0c;所以首先需要安装JDK,本教程默认已安装JDK1.8 未安装JDK可看JDK安装教程&#xff1a;JDK1.8安装教程 一、Tomcat下载和安装 1、首先进入Apache Tomcat官网&…

ATLAS/ICESat-2 L3B Monthly Gridded Atmosphere (大气月度网格数据集)V005

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Monthly Gridded Atmosphere V005 简介 该产品报告每周全球云覆盖率、海洋上总列光学深度、极地云覆盖率、风吹雪频率、视表面反照率以及地面探测频率。 参数&#xff1a;云光学…