【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, () > { //此模块…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...





















