从陌生到熟练使用string类

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解C++中有关string类的使用,从构造函数到容量操作,到遍历以及增删查改和最后的运算符重载.
目录
- 一、构造函数
- 二、容量(`capacity`)相关的操作
- (1)size()和length()
- (2)resize()与reserve()
- (3)clear()和empty()
- 三、访问与遍历
- 四、增删改查
- (1)追加字符/字符串(append)
- (2)查找(`find`)/切割(`substr`)
- 五、运算符重载
- `+`运算符重载与`getline()`
一、构造函数
string库的学习:传送门
在库中我们可以看到,string类的构造函数是很丰富的.
重点掌握牛牛框起来的四个哦,其他的忘记了咱可以查文档.

构造函数使用演示:
void test1()
{//无参构造 string();string s1; cout << "s1= " << s1 << endl;//拷贝构造, string (const string& str);s1 += "HELLO CSDN!!!";//下面讲,这里是为了s1里面有数据,方便拷贝构造string s2(s1);cout << "s2= " << s2 << endl;//用另一个string类的字串初始化 string (const string& str, size_t pos, size_t len = npos);string s3(s1, 6,4);cout << "s3= " << s3 << endl;//使用字符串进行初始化 string (const char* s);string s4("CJN Rush Rush Rush");cout << "s4= " << s4 << endl;//string(const char* s, size_t n);string s5("CJN Rush Rush Rush",7);//不常用cout << "s5= " << s5 << endl;//string(size_t n, char c);string s6(5, 'X');//不常用cout << "s6= " << s6 << endl;
}
运行结果:
s1=
s2= HELLO CSDN!!!
s3= CSDN
s4= CJN Rush Rush Rush
s5= CJN Rus
s6= XXXXX

二、容量(capacity)相关的操作
我们看一下库中对capacity(容量)的相关操作有哪些.

(1)size()和length()
其实size()和length()并没有本质区别.
都是用于返回string中字符串的有效字符长度.
但是,由于string实现的比较早,当时设计的是length(),后来STL出来以后,为了统一,增加了size()接口.
string s1;string s2("hello");//size和length并没有什么区别.cout << s1.size() << " " << s1.length() << endl;cout << s2.size() << " " << s2.length() << endl;
0 0
5 5
(2)resize()与reserve()
resize()用于改变字符串的有效字符长度.不够的地方用第二个参数填充.
string s3("HELLO CSDN!!!");s3.resize(5); //将字符串的有效字符长度改为5cout << s3 << endl;string s4("HELLO CSDN!!!");s4.resize(25,'x'); //将字符串的有效字符长度改为25,不够的地方用字符'x'填充cout << s4 << endl;
运行结果:
HELLO
HELLO CSDN!!!xxxxxxxxxxxx
resize()的改变会影响capacity(容量)吗?
string s5("HELLO CSDN!!!");cout << "s5.capacity=" << s5.capacity() << endl;s5.resize(25, 'x');cout << "s5.capacity=" << s5.capacity() << endl;s5.resize(5, 'x');cout << "s5.capacity=" << s5.capacity() << endl;//并没有缩容
运行结果:
s5.capacity=15
s5.capacity=31
s5.capacity=31
当然,如果容量太小,不足以存储有效字符,必然是会扩容的!
扩容选择:(扩容方式是未定义的)
扩容是按有效字符长度扩容.
按之前容量的1.5倍扩容,更或者是2倍扩容.
reserve():请求改变容量的大小.
string s6("HELLO CSDN!!!");cout << "s6.capacity=" << s6.capacity() << endl;s6.reserve(50);cout << "s6.capacity=" << s6.capacity() << endl;s6.reserve(30);cout << "s6.capacity=" << s6.capacity() << endl;//并没有缩容//一般都是不缩容的,缩容行为是未定义的.s6.clear();s6.reserve(0);cout << "s6.capacity=" << s6.capacity() << endl;//这里缩容了
s6.capacity=15
s6.capacity=63
s6.capacity=63
s6.capacity=15
是否缩容是未定义行为,取决于编译器,这里如果不清楚数据,直接将reserve(0),依旧不会缩容.
(3)clear()和empty()
string s7;cout << s7.empty() << endl;s7 += "HELLO";cout << s7.empty() << endl;cout << "s7.size=" << s7.size() << endl;cout << "s7.capacity" << s7.capacity() << endl;s7.clear();cout << "s7.size=" << s7.size() << endl;cout << "s7.capacity" << s7.capacity() << endl;
运行结果:
1
0
s7.size=5
s7.capacity15
s7.size=0
s7.capacity15
显然clear只是清除有效字符,将字符清零,并不会影响capacity容量.
(4)小结:
-
size()和length()底层实现原理是一样的,都是返回有效的字符个数.只是为了STL的接口相统一. -
resize(size_t n)与resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。
注意:resize在改变元素个数时.
(1)如果是将元素个数增多,可能会改变底层容量的大小,不然存储不了那么多有效字符.
(2)如果是将元素个数减少,底层空间总大小不变。 -
reserve((size_t res_arg=0))函数是请求改变string的容量.
(1)当res_arg大于当前的容量的时候,会进行扩容.
(1)当res_arg小于当前的容量的时候,一般不会缩容. -
clear只是清除有效字符,将字符清零,并不会影响capacity容量.
三、访问与遍历
正向迭代器与反向迭代器:(这里对C++11的用法暂时不介绍)

下标访问符 方括号[ ]重载

示例:
void test3()
{string s1("This is a little boy");string::iterator it = s1.begin(); //s1.begin()会返回有效字符串中第个元素的位置while (it != s1.end()) //s1.end()会返回有效字符串最后一个元素的位置的后一个位置{cout << *it ;it++;}cout << endl;string::reverse_iterator rit = s1.rbegin();//反向迭代器while (rit != s1.rend()) //s1.end()会返回有效字符串最后一个元素的位置的后一个位置{cout << *rit;rit++;}cout << endl;cout << "s1.begin=" << *(s1.begin()) << endl;cout << "s1.end=" << *(s1.end()-1) << endl; //不可直接访问s1.end(),因为不是有效字符,而是最后一个有效字符的下一个位置.cout << "s1.rbegin=" << *(s1.rbegin()) << endl;cout << "s1.rend=" << *(s1.rend()-1) << endl; //这里为什么是+1而不是-1,留在后面的专门反向迭代器讲解//可以像数组一样用下标直接访问cout << s1[0] << endl;cout << s1[3] << endl;cout << s1[8] << endl;
}
四、增删改查
(1)追加字符/字符串(append)

void test4()
{string s1("hello C");cout << "s1=" << s1 << endl;//尾插一个字符s1.push_back('S');s1.push_back('D');s1.push_back('N');cout << "s1=" << s1 << endl;cout << "----------------------------------" << endl;string s2("hello C");cout << "s2=" << s2 << endl;s2.append("SDN"); //追加字符串cout << "s2=" << s2 << endl;cout << "----------------------------------" << endl;string s3("hello C");cout << "s3=" << s3 << endl;s3 += "SDN"; //最喜欢使用这个,易读也简单cout << "s3=" << s3 << endl;
}
个人感想:
push_back一次插入一个字符太麻烦了,append虽然可以追加字符串,但是终究是没有+=来的香.
其它的以assign为例,一般用不到(因为实现的有些冗余,可以用别的函数代替),实在要用查库即可:
void test5()
{string str("This is a little boy");string s1,s2,s3;s1.assign(str);s2.assign(str, 8, string::npos);s3.assign(5, 'c');cout << "s1=" << s1 << endl;cout << "s2=" << s2 << endl;cout << "s3=" << s3 << endl;
}
运行结果:
s1=This is a little boy
s2=a little boy
s3=ccccc
(2)查找(find)/切割(substr)

c_str:为了与C语言兼容,返回C形式的常量字符串.
find:可以查找目标字符/字符串.
string substr (size_t pos = 0, size_t len = npos) const:从pos往后len个字符,返回这段被切割的字符串的副本.
void test6()
{string s1("This is a little boy");const char* arr = s1.c_str(); //返回C形式的常量字符串cout << "arr=" << arr << endl;string s2("This is a little boy");cout << s2.find('i') << endl; //查找目标字符cout << s2.find("little") << endl; //查找目标字符串string s3("321xxxxxxx@qq.com");int pos1 = s3.find('@');int pos2 = s3.find(".com");string s4, s5, s6;s4 = s3.substr(0, pos1-1); //从0位置开始,往后pos-1个字符s5 = s3.substr(pos1, s3.size() - pos2 - 1);s6 = s3.substr(pos2); //第二个参数为往后的字符个数,不写,默认为nposcout << "s4= " << s4 << endl;cout << "s5= " << s5 << endl;cout << "s6= " << s6 << endl;
}
运行结果:
arr=This is a little boy
2
10
s4= 321xxxxxx
s5= @qq
s6= .com
五、运算符重载
小知识点:
npos是-1,只不过类型是const size_t,所以是整数的最大值,通常表示字符串的结尾或无效位置。npos定义在std命名空间中,通常用于字符串的查找操作。



+运算符重载与getline()
void test7()
{string s1("HELLO ");string s2("CSDN");string s3;s3 = s1 + s2; //因为是传值返回,所以效率不高,建议少用cout << s3 << endl;string name;cout << "Please, enter your full name: ";getline(cin, name);cout << "Hello, " << name << "!\n";}
比较运算符这里就不一 一介绍了,字符串按ASCII码值进行比较.

string类的使用还是需要多多练习,可以试着写一下相关的oj题练一下手,后续会模拟实现string类,加深对string类的理解.
string相关习题1
今天就讲到这里了,我们下次模拟实现见.

相关文章:
从陌生到熟练使用string类
🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏1: 🍔🍟🌯C语言初阶 🐻推荐专栏2: 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 …...
ERP规划
ERP规划是指一个组织或企业在实施企业资源计划(ERP)系统之前,对其整体目标、需求和资源进行评估和规划的过程。以下是ERP规划的一般步骤和要点: 制定目标:明确组织对ERP系统的期望和目标,例如提高经营效率、…...
统计学作业啊啊啊啊
题目1 一个制药公司宣称其新药可以将病患的恢复时间从10天降至8天。为了验证这一声明,您从服用新药的病患中抽取了一个样本,发现样本均值为9天,样本标准差为2天,样本量为30。使用0.05的显著性水平进行假设检验,判断公…...
CAM实现的流程--基于Pytorch实现
CAM实现的流程 CAM类激活映射CAM是什么CAM与CNN CAM类激活映射 CAM是什么 可视化CNN的工具, CAM解释网络特征变化,CAM使得弱监督学习发展成为可能,可以慢慢减少对人工标注的依赖,能降低网络训练的成本。通过可视化,就…...
FL Studio2023最新版本21.1中文水果音乐编曲工具
虚拟乐器和真实乐器的区别?真实乐器指的是现实中需要乐手演奏的乐器,而虚拟乐器是计算机音乐制作中编曲师使用的数字乐器。FL Studio虚拟乐器插件有哪些?下文将给大家介绍几款FL Studio自带的强大虚拟乐器。 一、虚拟乐器和真实乐器的区别 …...
数据库概述SQL基本语法
基本概念 数据库DB database简称DB: 存储数据的仓库,是以某种结构存储数据的文件。指长期保存在计算机的存储设备上,按照一定规则阻止起来,可以被用户或应用共享的数据集合。 数据库管理系统DBMS 用于创建,维护,使…...
【面试】一文讲清组合逻辑中的竞争与冒险
竞争的定义:组合逻辑电路中,输入信号的变化传输到电路的各级逻辑门,到达的时间有先后,也就是存在时差,称为竞争。 冒险的定义:当输入信号变化时,由于存在时差,在输出端产生错误&…...
无涯教程-PHP - 性能优化
根据Zend小组的说明,以下插图显示了PHP 7与PHP 5.6和基于流行的基于PHP的应用程序上的HHVM 3.7。 Magento 1.9 与执行Magento事务的PHP 5.6相比,PHP 7的运行速度证明是其两倍。 Drupal 7 在执行Drupal事务时,与PHP 5.6相比,PHP 7的运行速度…...
如何在PHP中使用字符串
引言 字符串是由一个或多个字符组成的序列,可以由字母、数字或符号组成。所有的书面通信都是由字符串组成的。因此,它们是任何编程语言的基础。 在本文中,您将学习如何创建和查看字符串的输出,如何使用转义序列,如何连…...
Mybatis简单入门
星光下的赶路人star的个人主页 夏天就是吹拂着不可预期的风 文章目录 1、Mybatis介绍1.1 JDBC痛点1.2 程序员的诉求1.3 Mybatis简介 2、数据准备2.1 数据准备2.2 建工程2.3 Employee类2.4 Mybatis的全局配置2.5 编写要执行的SQL2.6 编写java程序2.7 稍微总结一下流程 3、解决属…...
【Linux】数据链路层:以太网协议
约束不等于压迫,冷静和理性不等于冷淡和麻木。 文章目录 一、以太网帧 和 局域网转发数据包1.局域网转发的原理(基于以太网协议)2.以太网MTU与MAC地址 二、局域网中的数据碰撞1.如何解决局域网中的数据碰撞?(碰撞检测和…...
docker搭建私有镜像harbor
docker安装搭建私有仓库 Harbor harbor用于存储和分布docker镜像企业级registry服务器的harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。 安装harhor 启动harbor 6....
汽车便携轮胎充气泵方案
便携式充气泵是一种小巧便捷的充气工具,可广泛应用于汽车、自行车、摩托车、游泳圈、球类等充气产品的充气过程中。该产品以其小巧轻便、充气效率高、操作简单等特点备受消费者的青睐。 充气泵工作过程 当电动机启动时,通过电磁离合器将气泵内的活塞带动…...
一、Kafka概述
目录 1.3 Kafka的基础架构 1.3 Kafka的基础架构 Producer:消息生产者,就是向 Kafka broker 发消息的客户端Consumer:消息消费者,向 Kafka broker 取消息的客户端。Consumer Group(CG):消费者组&…...
【数据结构OJ题】合并两个有序链表
原题链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 可以先创建一个空链表,然后依次从两个有序链表中选取最小的进行尾插操作。(有点类似双…...
C++ LibCurl 库的使用方法
LibCurl是一个开源的免费的多协议数据传输开源库,该框架具备跨平台性,开源免费,并提供了包括HTTP、FTP、SMTP、POP3等协议的功能,使用libcurl可以方便地进行网络数据传输操作,如发送HTTP请求、下载文件、发送电子邮件等…...
自然语言处理从入门到应用——LangChain:索引(Indexes)-[向量存储器(Vectorstores)]
分类目录:《自然语言处理从入门到应用》总目录 Vectorstores是构建索引的最重要组件之一。本文展示了与VectorStores相关的基本功能。在使用VectorStores时,创建要放入其中的向量是一个关键部分,通常通过嵌入来创建。 from langchain.embedd…...
【C++练习】普通方法+利用this 设置一个矩形类(Rectangle), 包含私有成员长(length)、 宽(width), 定义一下成员函数
题目 设置一个矩形类(Rectangle), 包含私有成员长(length)、 宽(width), 定义成员函数: void set_ len(int l); //设置长度 设置宽度void set_ wid(int w); 获取长度: int get len(); 获取宽度: int get _wid); 显示周长和面积: v…...
电子电路学习笔记之SA1117BH-1.2TR——LDO低压差线性稳压器
关于LDO调节器(Low Dropout Regulator)是一种电压稳压器件,常用于电子设备中,用于将高电压转换为稳定的低电压。它能够在输入电压和输出电压之间产生较小的差异电压,因此被称为"低压差稳压器"。 LDO调节器通…...
【LeetCode-面试经典150题-day7】
392.判断子序列 题意: 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是&quo…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
