C++初阶——string(字符数组),跟C语言中的繁琐设计say goodbye
前言:在日常的程序设计中,我们会经常使用到字符串。比如一个人的身份证号,家庭住址等,只能用字符串表示。在C语言中,我们经常使用字符数组来存储字符串,但是某些场景(比如插入,删除)下操作起来很繁琐。在C++中,底层设计了一个string类,将经常使用的功能封装在其中,使用起来非常简单,便捷。
本文主要介绍string的使用方法和几个常用函数,最后再列举几个经典例题。
我们使用string时经常会用到它封装的函数,这里推荐一个网站:C++ Reference。函数忘了怎么使用时可以参考该网站。
目录
- 一.介绍
- 二.使用
- 1.创建一个字符数组存储字符串hello world:
- 2.截取部分字符串
- 3.从键盘上输入
- 三.常用重载运算符和函数
- 1.+/+=
- 2.size()
- 3.capacity()
- 4.reserve()
- 5.[]运算符(遍历string)
- 6.push_back()(尾部插入一个字符)
- 7.append() (尾部插入一段字符串)
- 8.insert() (头部插入)
- 四.迭代器
- 1.iterator 正向迭代器(重点)
- 2.reverse_iterator 反向迭代器
- 3.reverse函数(字符串逆置神器)
- 五.例题
- 1.字符串相加
- 2.字符串最后一个单词长度
- 3.反转字符串中的单词 III
一.介绍
长话短说,不将它讲的太神秘:
string是用字符的顺序数组实现的类,用于管理字符数组。
我们平常怎么使用自定义的类,就怎么使用string。
二.使用
1.创建一个字符数组存储字符串hello world:
格式:
string 对象("字符或字符串")
1.形如string str2("hello world"),实际上就是调用string类的构造函数初始化对象str2.
2.string类中有流提取流插入运算符重载,可以直接输出或者输出string类型数据。
//C语言
char str1[] = "hello world";
//C++
string str2("hello world"); //构造函数
string str3("#"); //单个字符
cout << str2 << endl; //string类中有流提取流插入运算符重载,可以直接输出或者输出string类型数据。
控制台输出如下:
2.截取部分字符串
string类对此也进行了设计:第一个参数为截取string对象,第二个为需要截取部分的起始下标,第三个参数为截取字符个数(单位是字节);
如下代码:想截取s1对象中的world给给s2,w的下标为6(第二个参数),world有5个字符(第三个参数)
int main()
{string s1("hello world");string s2(s1, 6, 5); //截取s1对象中的world给给s2cout << s2 << endl;
}
控制台输出如下,可以看到截取成功了:
3.从键盘上输入
这里就可以体现string的优点:
使用C语言,我们需要考虑给字符数组开多大的空间,而string不用我们考虑这点,我们只管输入,编译器会自动帮我们适配合适的空间。
int main()
{string s1; //实例化一个对象s1cin >> s1; // 输入cout << s1 << endl; //打印return 0;
}
如下:前两行为从键盘上输入的,后两行为打印的。

三.常用重载运算符和函数
string函数设计的接口,感兴趣的可以去文章开头给的网站看看。下面某些函数只给出常用的接口。
1.+/+=
单从这个题目,就能让你感受到string的魅力!
请看题目:从键盘上输入两个字符串,要求将后一个字符串拼接到前一个字符串后面,输出拼接后的前一个字符串。(字符串长度不超过50字节)
从C语言角度考虑:首先我们要开两个不小于50字节的字符数组,之后简单一点的就是使用strcat函数拼接。但是strcat函数长久不用我忘掉了呢,还要再去翻看笔记回忆。
C++string类对+运算符进行了重载,这个+的本质就是尾插:
int main()
{string s1, s2;cin >> s1 >> s2;s1 = s1 + s2; //s1,s2顺序不能颠倒//s1 += s2; //使用+=也可以cout << s1 << endl;return 0;
}
控制台输出如下:其中第一行为输入的s1,第二行为输入的s2,第三行为拼接后的s1
2.size()
返回string对象的有效字符长度(不包括\0),相当于C语言的strlen。
int main()
{string s1("hello world");cout << s1.size() << endl;return 0;
}
控制台输出如下:

3.capacity()
返回string对象的容量
我们知道string会自动扩容,而它当然不是一个一个字节阔的,它是按照一定倍率扩容。
int main()
{string s1("hello world");cout << "size:" << s1.size() << endl;cout << "capacity:" << s1.capacity() << endl;return 0;
}
控制台输出如下:可以看到有效字符大小为11字节,容量为15字节。
4.reserve()
reserve——保留(不要把它当成reverse(逆置))
功能:请求容量的变化
价值:如果确定大概需要开多大的空间,可以提前开好,减少扩容,提高效率。(扩容是有代价的,特别是异地扩容,需要拷贝旧空间的数据移到新空间)
int main()
{string s1("hello world");cout << "size:" << s1.size() << endl;cout << "原capacity:" << s1.capacity() << endl;s1.reserve(100);cout << "新capacity:" << s1.capacity() << endl;return 0;
}
控制台输出如下:
5.[]运算符(遍历string)
string类对[]运算符进行了重载,使得我们可以借助[]像访问数组一样访问string。对于解决一些与字符串有关的题很有帮助。
以遍历string为例:
int main()
{string s1("hello world");for (size_t i = 0; i < s1.size(); i++) //运用size()函数{cout << s1[i] << " "; //下标访问}return 0;
}
控制台输出如下:
6.push_back()(尾部插入一个字符)
在string对象尾部插入一个字符
int main()
{string s1("hello world");s1.push_back('x');cout << s1 << endl;return 0;
}
控制台输出如下:
7.append() (尾部插入一段字符串)
形式:append(字符串/string对象)
实际上设计的有些冗余,插入的话我们直接用+=就行了,何必再使用append函数呢?
int main()
{string s1("hello world");string s2("!!!");s1.append("xxx");s1.append(s2);cout << s1 << endl;return 0;
}
控制台输出如下:
8.insert() (头部插入)
插入一个字符:
1.常规做法:s.insert(起始位置下标,插入个数,要插入字符)
2.迭代器做法:s.insert(s.begin(),要插入字符)
int main()
{string s1("hello world");string s2("hello world");string s3("hello world");s1.insert(1,1,'x'); // 在h后插入一个xs2.insert(1, 2, 'x'); // 在h后插入两个x s3.insert(s3.begin(), 'x'); // 头插x cout << "s1 = " << s1 << endl; //hxello worldcout << "s2 = " << s2 << endl; //hxxello worldcout << "s3 = " << s3 << endl; //xhello worldreturn 0;
}
插入一段字符串:s.insert(起始位置下标,字符串)
int main()
{string s1("hello world");s1.insert(1,"xx");cout << s1 << endl; //hxxello worldreturn 0;
}
四.迭代器
1.iterator 正向迭代器(重点)
| 函数名 | 作用(下面函数仅适用于正向迭代器!!!) |
|---|---|
| begin() | 返回string开头的地址 |
| end() | 返回string最后一个有效字符的下一个位置的地址(一般都是\0) |
iterator是迭代器的意思,它封装在string类中(list,树等数据结构中都有迭代器),故而使用时要受string类域限制,要写成
string::iterator形式。使用时可以将它想象成一个指针来理解。
借助迭代器遍历string:
int main()
{string s1("hello world");string::iterator str = s1.begin();//auto str = s1.begin(); 写成这样也可以,auto是类型指示符,可以根据begin推出正向迭代器while (str != s1.end()) {cout << *str << " ";++str;}cout << endl;return 0;
}
控制台输入如下:
上述代码借助begin()函数返回开始位置的迭代器,end()指向最后一个字符下一个位置(此处就是\0)。
问:可这样子不就是单纯的指针遍历吗,何必那么麻烦还使用迭代器?
答:迭代器的一个特点就是通用性,在vector,list,树等中都有迭代器。就以list举例,它是由一个一个的小结点组成的,物理空间中并不是连续的,使用结点指针++并不能找到它的下一个结点,但是像上述代码一样套上迭代器就可以遍历list。因此,迭代器遍历才是最主流的遍历方式。
2.reverse_iterator 反向迭代器
| 函数名 | 作用(下面函数仅适用于反向迭代器!!!) |
|---|---|
| rbegin() | 返回string最后一个有效字符的下一个位置的地址(一般都是\0) |
| rend() | 返回string开头的地址 |
顾名思义,跟正向迭代器相反,reverse_iterator是反正使用的。
借助反向迭代器倒着遍历string:
int main()
{string s1("hello world");string::reverse_iterator str = s1.rbegin();//auto str = s1.rbegin(); 写成这样也可以,auto是类型指示符,可以根据rbegin推出反向迭代器while (str != s1.rend()){cout << *str << " ";++str;}cout << endl;return 0;
}
控制台输入如下,可以看到它是倒着遍历的:
补:const迭代器:const_iterator const_reverse_iterator
总计共有4种迭代器。
3.reverse函数(字符串逆置神器)
传入迭代器区间: reverse(s.begin(),s.end());
int main()
{string s1("hello world");reverse(s1.begin(), s1.end()); //传入迭代器区间cout << s1 << endl;return 0;
}
控制台输出如下:
五.例题
1.字符串相加
点击链接
高精度,不能用整型或长整型直接相加。
运用string一位一位相加进位。
class Solution {
public:string s;string addStrings(string num1, string num2) {int end1 = num1.size()-1,end2 = num2.size()-1;int ret = 0,sum = 0;while(end1 >= 0 || end2 >= 0){int n1 = end1>=0?num1[end1]-'0':0;int n2 = end2>=0?num2[end2]-'0':0;sum = n1+n2+ret;ret = sum/10;s += sum%10+'0';--end1;--end2;}if(ret == 1)s += '1';reverse(s.begin(),s.end());return s;}
};
2.字符串最后一个单词长度
1.牛客要包头文件 < string >
2.rfind()若没找到,返回无符号的-1
3.string::npos == 无符号的-1
4.注意只有一个单词的情况
#include <iostream>
#include<string>
using namespace std;
int main()
{string s1;getline(cin,s1);size_t eblack = s1.rfind(' '); //倒着找第一个空格,没找到返回无符号的-1if(eblack != string::npos){cout << s1.size()-(1+eblack); //下标-1}else {cout << s1.size();}return 0;
}
3.反转字符串中的单词 III
点击链接
运用迭代器reverse函数
class Solution {
public:string reverseWords(string s) {int i = 0,k = 0;while(s[i]!='\0'){if(s[i] == ' ') //找空格{reverse(s.begin()+k,s.begin()+i); //借助reverse反转单词k = i + 1;}i++;}reverse(s.begin()+k,s.end()); //反转仅有或仅剩一个单词的情况return s;}
};
文末BB:对哪里有问题的朋友,尽管在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给博主点点赞和关注.

相关文章:
C++初阶——string(字符数组),跟C语言中的繁琐设计say goodbye
前言:在日常的程序设计中,我们会经常使用到字符串。比如一个人的身份证号,家庭住址等,只能用字符串表示。在C语言中,我们经常使用字符数组来存储字符串,但是某些场景(比如插入,删除)下操作起来很…...
Android Bitmap详解(下)之图片缓存详解
前言: 之前有出过俩篇关于bitmap相关的讲解,分别是Bitmap详解(上)常用概念和常用API和Bitmap详解(中)之像素级操作,今天主要是来一个系统的总结。 认识Bitmap: Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像…...
020-从零搭建微服务-认证中心(九)
写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址(后端):https://gitee.com/csps/mingyue 源码地址(前端):https://gitee.com/csps…...
孤注一掷中的黑客技术
最近孤注一掷电影很火,诈骗团伙的骗术实在厉害,就连电影中的黑客潘生都未能幸免。电影中的陆经理说:不是我们坏, 是他们贪。这句话我觉得有一部分是对的,诈骗分子抓住了人的本性贪婪,才使得被骗的人逐步走向…...
机器学习笔记 - PyTorch Image Models图像模型概览 (timm)
一、简述 PyTorch Image Models (timm)是一个用于最先进的图像分类的库,包含图像模型、优化器、调度器、增强等的集合;是比较热门的论文及代码库。 虽然越来越多的低代码和无代码解决方案可以轻松开始将深度学习应用于计算机视觉问题,但我们经常与希望寻求定制解决方案的客户…...
Java 实现证件照底图替换,Java 实现照片头像底图替换
效果图 这里前端用layui实现的案例截图 color底图颜色可以在网页上这样取色 new Color(34, 133, 255) 实现案例下载链接:https://download.csdn.net/download/weixin_43992507/88237432...
周易卦爻解读笔记——未济
第六十四卦未济 火水未济 离上坎下 未济卦由否卦所变,否卦六二与九五换位,象征尚未完成。 天地否 未济卦和既济卦既是错卦又是覆卦,这也是最后一卦,序卦传【物不可穷也,故受之以未济终焉】 未济卦象征尚未完成&…...
AI 绘画Stable Diffusion 研究(十三)SD数字人制作工具SadTlaker使用教程
免责声明: 本案例所用安装包免费提供,无任何盈利目的。 大家好,我是风雨无阻。 想必大家经常看到,无论是在产品营销还是品牌推广时,很多人经常以数字人的方式来为自己创造财富。而市面上的数字人收费都比较昂贵,少则几…...
伦敦金走势图行情值得关注
不知道大家是否了解过伦敦金这个投资品种,或者有否财经网站以及金融终端上看到过它的行情走势图。其实,伦敦金并不是一种实实在在的黄金,而是一种跟踪伦敦现货黄金市场价格走势的黄金保证金交易品种,它每天的行情走势变化…...
机器学习之数据清洗
一、介绍 数据清洗是机器学习中的一个重要步骤,它涉及对原始数据进行预处理和修复,以使数据适用于机器学习算法的训练和分析。数据清洗的目标是处理数据中的噪声、缺失值、异常值和不一致性等问题,以提高数据的质量和准确性。 二、方法 处理…...
T599聚合物电容器:在汽车应用中提供更长的使用寿命的解决方案
自从电子技术被引入汽车工业以来,汽车的技术含量一直在提升。诸多技术被应用在汽车上,使汽车的形象更接近于轮子上的超级计算机。更多传感器、更强大的计算能力和电力被装载到汽车上,汽车应用中的电子产品数量正在迅速增长。随着电动汽车和自…...
学习ts(五)类
定义 是面向对象程序设计(OOP)实现信息封装的基础 类是一种用户定义的引用数据类型,也称类类型 JavaScript的class,虽然本质是构造函数,但是使用起来已经方便了许多,js中没有加入修饰符和抽象类等特性 ts的class支持面…...
EasyImage简单图床 - 快速搭建私人图床云盘同时远程访问【无公网IP内网穿透】
憧憬blog主页 在强者的眼中,没有最好,只有更好。我们是移动开发领域的优质创作者,同时也是阿里云专家博主。 ✨ 关注我们的主页,探索iOS开发的无限可能! 🔥我们与您分享最新的技术洞察和实战经验࿰…...
从SVG到Canvas:选择最适合你的Web图形技术
SVG 和 Canvas 都是可以在 Web 浏览器中绘制图形的技术。 众所周知, icon 通常使用 svg(如 iconfont),而交互式游戏采用 Canvas。二者具体的区别是什么?该如何选择? 声明式还是命令式?绘制的图形…...
基于 Redis 实现分布式限流
基于 Redis 实现分布式限流 一、 简介二、分布式限流1 数据结构1.1 Redis List1.2 Redis Set1.3 Redis Sorted Set 2 实现分布式限流3 实现原理分析 三、分布式限流算法1. 计数器算法2. 漏斗算法3. 令牌桶算法 四、分布式限流实战1. 单机限流实现2. 基于Redis Clusters的分布式…...
前端下载文件方式(Blob)
以下以下载图标svg文件为例,实现点击按钮下载文件,其中icon结构如下: const DownloadSvg (props) > {function download(downfile) {const tmpLink document.createElement("a");const objectUrl URL.createObjectURL(downfi…...
【STM32】FreeRTOS软件定时器学习
软件定时器 FreeRTOS提供了现成的软件定时器功能,可以一定程度上替代硬件定时器,但精度不高。 实验:创建一个任务,两个定时器,按键开启定时器,一个500ms打印一次,一个1000ms打印一次。 实现&…...
【LeetCode】复写零
复写零 题目描述算法描述编程代码 链接: 复写零 题目描述 算法描述 编程代码 class Solution { public:void duplicateZeros(vector<int>& arr) {int n arr.size();int dest -1,cur 0;while(cur < n){if(arr[cur]){dest;}else{dest2;}cur;if(dest > n-1){…...
使用docker-maven-plugin插件构建镜像并推送至私服Harbor
前言 如下所示,建议使用 Dockerfile Maven 插件,但该插件也停止维护更新了。因此先暂时使用docker-maven-plugin插件。 一、开启Docker服务器的远程访问 1.1 开启2375远程访问 默认的dokcer是不支持远程访问的,需要加点配置,开…...
YOLO目标检测——动漫头像数据集下载分享
动漫头像数据集是用于研究和分析动漫头像相关问题的数据集,它包含了大量的动漫风格的头像图像。动漫头像是指以动漫风格绘制的虚构人物的头像图像,常见于动画、漫画、游戏等媒体。 数据集点击下载:YOLO动漫头像数据集50800图片.rar...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...













