【C++精华铺】9.STL string
目录
1. string类的优势
2. string类的常用接口
2.1 常用构造
1. 空串构造:string();
2. C串构造:string(const char* s);
3. 拷贝构造:string(const string& str);
4. 字符填充构造:string(size_t n, char c);
5. 迭代器构造:string(InputIterator first, InputIterator last);
2.2 string容量操作
1. size_t size(),size_t length()
2. size_t capacity() const
3. bool empty() const
4. void clear()
5. void reserve(size_t n = 0)
6. void resize(size_t n), void resize(size_t char c)
2.3 类对象的访问
1. char& operator[](size_t pos),const char& operator[](size_t pos) const
2. begin()、end()
3. rbegin()、rend()
2.4 string对象处理函数
1. push_back()
2. append()
3. operator+=
4. c_str()
5. insert()
6. erase()
7. find()、rfind()
8. substr()
9. getline()
1. string类的优势
STL(Standard Template Library)库中的string类是一个字符串类,它提供了管理字符串的各种方法和功能。它是一个可变长度的字符序列,可以自动调整自身大小以适应字符串的长度变化。
在之前我们操作字符串都是通过自己去实现相关的函数来进行操作,而且稍不留神就会内存泄漏,在C++中我们更倾向于使用string类来完成和字符串相关的操作。
使用string类相比于使用C语言的字符串有以下优点:
-
更加安全:C语言的字符串没有自带长度信息,容易造成内存越界等安全问题。而string类包含有字符串长度信息,能够避免这类问题。
-
更加方便:C语言中处理字符串需要使用一系列函数,如strlen、strcmp、strcat等等,使用起来比较繁琐。而string类提供了一系列方法,如length、compare、append等等,使用起来更加直观方便。
-
更加灵活:string类可以动态地改变字符串的长度,而C语言的字符串长度通常是固定的。
-
更加高效:string类内部实现了很多优化,如字符串复制采用了引用计数和写时复制等技术,因此性能相对于C语言的字符串更高。
2. string类的常用接口
2.1 常用构造
C++98中支持7种构造函数 ,如下:
- default (1) string();
- copy(2) string(const string& str);
- substring(3) string(const string& str, size_t pos, size_t len = npos);
- from c - string(4) string(const char* s);
- from sequence(5) string(const char* s, size_t n);
- fill(6) string(size_t n, char c);
- range(7) template <class InputIterator> string(InputIterator first, InputIterator last);
但是我们只对其中的五个进行讲解:
1. 空串构造:string();
这个构造函数会构造一个空字符串,长度为0个字符,但是容量不一定为零,比如在vs下空string对象的容量是15,不同环境可能有所不同,主要为了避免频繁的扩容操作。
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1; //创建一个空字符串cout << s1 << endl;cout << s1.capacity() << endl;
}
输出:
2. C串构造:string(const char* s);
以null结尾的字符序列(C串)构造string对象。
int main()
{string s1("hello world!");cout << s1 << endl;}
输出:
3. 拷贝构造:string(const string& str);
利用一个已经存在的string对象构造对象。
int main()
{string s1("hello world!");cout << s1 << endl;string s2(s1);cout << s2 << endl;
}
输出:
4. 字符填充构造:string(size_t n, char c);
利用n个字符构造string对象。
int main()
{string s1(5, 'c');cout << s1 << endl;
}
输出:
5. 迭代器构造:template <class InputIterator> string(InputIterator first, InputIterator last);
使用迭代器区间来构造string对象。
int main()
{string s1(5, 'c');cout << s1 << endl;string s2(s1.begin(), s1.end());cout << s2 << endl;
}
输出:
2.2 string容量操作
1. size_t size(),size_t length()
size()和length()都是返回字符串的有效字符长度,俩个函数的实现原理也完全相同,引入size()是为了和其他容器的接口保持一致。
int main()
{string s1(5, 'c');cout << s1.length() << endl;cout << s1.size() << endl;
}
输出:
2. size_t capacity() const
capacity()是返回空间的总大小,在vs下对象的初始容量是15,当存储的对象超过这个大小的时候才会去开空间,在新开的空间存储数据。
int main()
{string s1(5, 'c');cout << s1.capacity() << endl;string s2(16, 'c');cout << s2.capacity() << endl;
}
输出:
3. bool empty() const
检测字符串是否是空串,是返回true,不是返回false。
int main()
{string s1(5, 'c');if (s1.empty()){cout << "true" << endl;cout << "空" << endl;}else{cout << "false" << endl;cout << "非空" << endl;}
}
输出:
4. void clear()
清空对像中的有效字符。
int main()
{string s1("hello world!");cout << s1 << endl;cout << "--------------------------------" << endl;s1.clear();cout << s1 << endl;
}
输出:
5. void reserve(size_t n = 0)
reserve()是为了给对象预留空间,如果我们提前得知字符串需要的空间我们就可以提前开好,避免频繁扩容带来的性能消耗。当reserve的参数小于string底层空间大小的时候,reserve就不会对容量进行处理。(一般为了保障程序的安全性,reserve()会多开出一部分空间)。
int main()
{string s1(10,'x');s1.reserve(20);cout << s1.capacity() << endl;s1.reserve(2);cout << s1.capacity() << endl;
}
输出:
6. void resize(size_t n), void resize(size_t char c)
修改字符有效个数为n,多出的空间用字符c填充。如果n小于有效字符数,本质就是删字符操作。如果容量不够会扩容。
int main()
{string s1(10, 'x');cout << s1 << endl;s1.resize(20, 'c');cout << s1 << endl;s1.resize(2);cout << s1 << endl;
}
输出:
2.3 类对象的访问
1. char& operator[](size_t pos),const char& operator[](size_t pos) const
返回pos位的字符,并且可以对非const对象进行修改。
int main()
{string s1(10, '1');cout << s1 << endl;s1[4] = '0';cout << s1 << endl;for (int i = 0; i < 10; i++){cout << s1[i] << ' ';}
}
输出:
2. begin()、end()
begin()返回第一个字符位置的迭代器,end()返回最后一个字符的下一个位置的迭代器。begin()和end()都返回了自己的const版本。
int main()
{string s1(10, '1');auto it = s1.begin();for (; it < s1.end(); it++){cout << *it;}
}
输出:
3. rbegin()、rend()
rbegin()获取一个反向迭代器,指向其反向开头,rend()获取一个反向迭代器,指向其反向结尾的前一个理论元素。
int main()
{string s1("123456789");cout << s1 << endl;auto it = s1.rbegin();for (; it < s1.rend(); it++){cout << *it;}
}
输出:
2.4 string对象处理函数
1. push_back()
在字符串后尾插字符c。
int main()
{string s1;s1.push_back('1');cout << s1;
}
输出:
2. append()
append()函数在在C++98有六种重载形式,用于在字符串后追加一个字符串。
- string(1) string& append(const string& str);
- substring(2) string& append(const string& str, size_t subpos, size_t sublen);
- c - string(3) string & append(const char* s);
- buffer(4) string& append(const char* s, size_t n);
- fill(5) string& append(size_t n, char c);
- range(6) template <class InputIterator> string& append(InputIterator first, InputIterator last);
int main()
{string s1("hello");string s2(" world");cout << s1 << endl;s1.append(s2); //在s1结尾追加一个s1cout << s1 << endl;s1.append(s2, 1, 2); //在s1结尾追加s1的下标为1往后的俩个字符cout << s1 << endl;s1.append("C串"); //在s1后追加一个C串cout << s1 << endl;s1.append("123456", 2);//在s1后追加字符串的前 n 个字符。cout << s1 << endl;s1.append(5, 'c'); //在s1后追加5个字符‘c’cout << s1 << endl;string s3("CSDN");s1.append(s3.begin(), s3.end());//在s1后追加一个迭代器区间cout << s1 << endl;
}
输出:
3. operator+=
operator+=()和append()功能类似,都是在字符串后追加内容,但是我们在实际开发中更愿意使用operator+=。
int main()
{string s1("hello ");string s2("world!");s1 += s2;cout << s1 << endl;
}
输出:
4. c_str()
c_str()会返回string对象存储字符串的首地址,用户可以通过这个接口来适配c语言中的某些场景。
int main()
{string s1("hello world!");printf("%s", s1.c_str());
}
输出:
5. insert()
insert()支持在pos位对字符串进行插入操作,但是由于pos位插入涉及到元素的挪动,而挪动元素会使性能下降,所以insert()要少用。insert()有多种重载形式,如下:
- string(1) string& insert(size_t pos, const string& str);
- substring(2) string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);
- c - string(3) string & insert(size_t pos, const char* s);
- buffer(4) string& insert(size_t pos, const char* s, size_t n);
- fill(5) string& insert(size_t pos, size_t n, char c); void insert(iterator p, size_t n, char c);
- single character(6) iterator insert(iterator p, char c);
- range(7) template <class InputIterator> void insert(iterator p, InputIterator first, InputIterator last);
int main()
{string s1("string");cout << s1 << endl;s1.insert(2, "*********");cout << s1 << endl;
}
输出:
6. erase()
erase()是删除字符串的一部分,但是不会改变string对象的容量,如果给的删除字符个数大于pos位后的字符个数,会将后面的全部删除。如果没有给pos位,则默认清空字符串。如果不给删除个数则默认是无符号整型npos(-1)即约等于42亿,就会将pos位后面的字符序列全部删除。
- sequence(1) string& erase(size_t pos = 0, size_t len = npos);
- character(2) iterator erase(iterator p);
- range(3) iterator erase(iterator first, iterator last);
int main()
{string s1("1234567890");s1.erase(2, 3);//从pos位2开始依次删除三个字符,即删除"345"cout << s1 << endl;s1.erase(s1.begin() + 5);cout << s1 << endl;//删除迭代器位置的字符s1.erase(s1.begin(), s1.begin() + 2);//删除beigin()位置和后面1位字符cout << s1 << endl;
}
输出:
7. find()、rfind()
find()函数用于查找某字符串中是否包含某个字符或者字符串,会从pos位往后查找,rfind()则是从pos位往前查找。找到后会返回字符首次出现的pos位或者字符串首次出现的pos位。如果没有找到则会返回npos(无符号整型‘-1’)。
- string(1) size_t find(const string& str, size_t pos = 0) const;
- c - string(2) size_t find(const char* s, size_t pos = 0) const;
- buffer(3) size_t find(const char* s, size_t pos, size_t n) const;
- character(4) size_t find(char c, size_t pos = 0) const;
int main()
{string s1("hello world");size_t pos = s1.find("llo", 0);cout << pos << endl;
}
输出:
8. substr()
substr()会获取pos后包括pos位的n个字符并且返回一个string对象,如果没有给获取长度n,则会默认将后面的包括pos位的所有字符全部获取并且返回一个string对象。
- string substr(size_t pos = 0, size_t len = npos) const;
int main()
{string s1("123456789");cout << s1 << endl;string s2(s1.substr(2, 5));cout << s2 << endl;
}
输出:
9. getline()
从 istream 中提取字符并将其存储到 str 中,直到找到分隔字符 delim(或 (2) 的换行符“\n”)。如果在 is 中到达文件末尾或在输入操作期间发生其他错误,则提取也会停止。如果找到分隔符,则将其提取并丢弃(即不存储它,下一个输入操作将在它之后开始)。请注意,调用之前的任何内容都将替换为新提取的序列。每个提取的字符都追加到字符串中,就像调用其成员push_back一样。(不以空格作为分隔符,可以读取空格符)
- (1)istream& getline(istream& is, string& str, char delim);
- (2)istream& getline(istream& is, string& str);
相关文章:

【C++精华铺】9.STL string
目录 1. string类的优势 2. string类的常用接口 2.1 常用构造 1. 空串构造:string(); 2. C串构造:string(const char* s); 3. 拷贝构造:string(const string& str); 4. 字符填充构造:string(size_t n, char c); 5. 迭代…...

【PACS】医学影像管理系统源码带三维重建后处理技术
PACS系统,意为影像归档和通信系统。它是应用在医院影像科室的系统,主要的任务就是把日常产生的各种医学影像(包括核磁,CT,超声,各种X光机,各种红外仪、显微仪等设备产生的图像)通过各…...
从0开始学go 第一天
今天是开始学go的第x天,前些日子看了看语言,今天找一个web开发来跟着学,记录一下遇到的问题,方便以后复习查阅。 视频看的是https://www.bilibili.com/video/BV1gJ411p7xC?p3&vd_sourceab5bdbd04f4142027c66d604d5285204 视…...

Spring Cloud Nacos详解
目录 1、Spring Cloud Nacos详细介绍2、Spring Cloud Nacos具体案列 Spring Cloud Nacos 是一个由阿里巴巴集团开发的开源分布式系统服务发现、配置管理和服务管理的平台。Nacos 支持多种服务发现方式,包括 DNS 方式、HTTP 和 RPC 方式,同时提供了灵活的…...

2023谷歌开发者大会直播大纲「初稿」
听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…...

react import 引用失效 node_modules/@types/react/index.d.ts not a module.ts
问题描述 react ts的项目,正常使用vs code打开, 先运行 npm install 安装依赖过后 结果所有的react引用依旧标红,如下图所示: 点击红线 show problem(查看问题),提示node_modules/types/react/index.d.ts not a mod…...

Unity中的Unistorm3.0天气系统笔记
Unistorm是Unity中的一个天气系统,它功能强大,效果优美。本文所述UniStorm为3.0版本,仅用于学习之用。 一、如何设置【白天】、【黑夜】和【天气类型】? 在Running模式下,按下Esc按键,会【弹出】或者【隐…...

VMVareC++开发环境快速配置
OVERVIEW VMVareC开发环境快速配置ipgitvimgithubzshgcc&g&cmakesshifconfigmysqlnginxredisgdb VMVareC开发环境快速配置 VMVareC开发环境快速配置,为了省时间快速整理出文档方便以后快速配置, 按照这个流程直接可以快速得到一个舒适的C/C开发…...

数据库为什么使用B+树而不是B树做索引
🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…...
java必知必会--面向对象及相关基础知识
java必知必会–面向对象及相关基础知识 一、java面向对象: 1、什么是面向对象以及三大特性 ①我们把数据和数据之间的相互操作关系放到一起总结为–对象。所有的操作都是基于对象来进行的。 ②面向对象的的特征:封装、继承、多态 ③封装:我…...

【推荐】Spring与Mybatis集成
目录 1.概述 2.集成 2.1代码演示: 3.整合 3.1概述 3.2 进行整合分页 接着上两篇,我已经写了Mybatis动态之灵活使用,mybatis的分页和特殊字符的使用方式接下来把它们集成起来,是如何的呢👇👇…...

中科驭数受邀在招商银行金融科技论坛作异构计算主题分享 解码金融科技先进算力构建之路
8月25日,2023招银浦江金融科技论坛正式召开。中科驭数高级副总裁张宇受邀在资管科技分论坛发表《金融行业先进异构算力底座构建之路》的主题演讲,与参会嘉宾分享了当前计算系统的发展趋势以及如何通过异构算力构建IT技术底座来推动金融科技的创新。 ▲ 中…...
Maven打包方式pom和jar和war的区别
Maven 项目可以使用不同的打包方式,如 POM、JAR 和 WAR,这些方式决定了项目构建后生成的产物类型和用途。下面是这些打包方式的区别: 1. **POM (Project Object Model):** POM 打包方式实际上不会生成一个可执行的构建产物。它是…...

【51单片机】EEPROM-IIC实验(按键控制数码管)
目录 🎁I2C总线 编辑 🎁代码 🏳️🌈main.c 🏳️🌈i2.c 🎆代码分析 🎁I2C总线 I2C总线是Philips公司在八十年代初推出的一种串行、半双工的总线,主要用于近距…...

【java】【springboot】【idea】springboot项目pom.xml 灰色下划线
解决方案: 这里我们找到了原因,就是因为选择了Ignored Files导致pom.xml文件被设置在maven忽略文件清单中,所以我们将打勾的选项取消,点击Apply,然后点击OK...

[JavaWeb]【十四】web后端开发-MAVEN高级
目录 一、分模块设计与开发 1.1 分模块设计 1.2 分模块设计-实践编辑 1.2.1 复制老项目改为spring-boot-management 1.2.2 新建maven模块runa-pojo 1.2.2.1 将原项目pojo复制到runa-pojo模块 1.2.2.2 runa-pojo引入新依赖 1.2.2.3 删除原项目pojo包 1.2.2.4 在spring-…...

浏览器跨域
生活中的事跟跨域有什么关系,那必须有。 跨域的产生是浏览器的安全机制引起的,只有在使用Ajax时才会发生。简单来说就是你可以通过ajax发送请求,但要看远程服务器脸色,他没授权,浏览器这个老六就给拦截了,不…...

ffmpeg windows环境MinGW+msys2编译so库
一、安装MinGW 1.1、下载MinGW 1.2、下载完成后,会得到一个名为 mingw-get-setup.exe 的安装包,双击打开它,可以看到如下的对话框: 1.3、直接点击“Install”,进入下面的对话框 1.4、可根据自己操作系统的实际情况&am…...

python VTK PyQt5 VTK环境搭建 创建 渲染窗口及三维模型,包含 三维模型交互;
目录 Part1. VTK 介绍 Part2. PyQt5 VTK环境搭建 安装Anaconda 自带Python Anaconda下载 安装PyQt5 安装 VTK Part3 :PyQt VTK 结合样例: Part1. VTK 介绍 VTK(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形…...
学习总结(二) node.js服务器如何使用net模块向硬件发送命令与接收数据?
服务器server.js: const net require("net"); //此模块用于tcp/ip通讯 当收到get请求时: server.get("/cfjcApi/v1/SkyTempHudi", (req, res) > { let client new net.Socket(); client.connect(网络模块端口, 网络模块Ip, () > { //此模块…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...