C++语言·string类

1. 为什么有string类

        C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数(strcpy,strcat),但是这些库函数与字符串是分离开的,不太符合OOP(Object Oriented Programming面向对象编程)的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

        所以在C++中用string类统一管理字符串和其方法,简化编程。其实string并不是一个正经的STL库中的内容,它的出现比STL略早,内容也没有STL中的别的模块成熟。

2. 标准库中的string类

2.1 string类

        官网资料:string - C++ Reference

        string是一个管理char的类模板,是一个管理字符的顺序表,或者说是一个字符数组。

        该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作,容器就是指栈、队列这些写好了可以装数据的东西。

        在使用string类时,要包含它的头文件 <string> 

2.2 string类的常用接口说明

2.2.1 string类的常见构造

        官网资料:string::string - C++ Reference

        98版中有7种构造方案其中1、2、4是比较常用的。

        1号构造:就是默认构造,会构造一个长度为0的空字符串

        2号、4号构造:拷贝构造,只不过参数不同,一个是string类型,一个是C字符串

        3号构造:从pos位置拷贝len个字符去构造,如果字符串较短,就能拷几个就拷几个。npos是一个size_t类型的-1,也就是24亿多的一个数,用这样一个字符串不可能达到的长度作为len的缺省值,其意义就是在不传len参的时候拷贝到字符串结尾

        5号构造:将一个C字符串的前n个字符拷贝构造

        6号构造:用n个字符c构造

        7号构造:用另一个string类对象的迭代区间构造

                        

        可能有的同学已经发现了我上面打印string的时候用的是流插入 << 操作符,当然是因为这个string类中为了方便我们进行打印写了友元重载函数。

2.2.2 string类对象的容量操作

2.2.2.1 size 与 length 与 capacity

        size 返回字符串有效数据个数(有效字符长度),不包括 '\0'

        length 返回字符串有效字符长度,不包括 '\0'

        那为什么要设计两个功能一样的成员函数呢,实际上这就是设计上的失误,在之后我们学的各种容器中,都是只有size没有length,length的出现只是一个特例。为了保持一致,今后我们也只使用size

        capacity 返回该string的容量,或者说string总空间的大小,因为string类中存了不止字符串本身的内容,所以其实际长度一定不等于字符串长度

                

        不过不用担心string的容量不够,string会自己扩容的,换句话说,当这个capacity填满了,就会扩容到更大的capacity。

2.2.2.2 empty 与 clear

        clear 清空有效字符

        empty 检测字符串是否为空串,是空返回true,不是空返回false

                  

2.2.2.3 reserve 与 resize

        reserve是给string扩容的,直接改变capacity的大小,当我们知道一个string需要多大空间的时候就可以提前reserve,把这块空间开好。当然,reserve改变capacity的大小,因此也可以缩容,但是VS下不支持缩容操作。

        注意,reserve(保留)  reverse(逆转),这俩个函数要分清楚,逆转函数reverse是算法函数,其参数是两个迭代器,用来控制将容器中迭代器所划分出来的数据顺序反转,如果用在string身上的含义就是反转字符串。

        resize 将有效字符的个数改成n个,多出的空间用选定的字符c填充,如果不指定字符c,编译器就会自动补上默认字符 '\0'

        resize因为给字符串本身扩容了,所以它也会影响capacity

        如果用resize强制缩短字符串长度,会使多出的字符串删掉,但是不会影响capacity的大小                                

2.2.2.4 shrink_to_fit

        这个是正经的缩容接口,当我们把一个很长的字符串删除多次之后会出现很多空出来的空间,造成一定程度上的浪费,此时就用这个接口让 capacity 的大小更适应字符串长度 size

        但是不要频繁缩容,因为缩容的本质是将原本大空间中的东西拷贝到小空间中去,这个过程会造成时间上的消耗。

2.2.3 string类对象的访问及遍历操作

2.2.3.1 operator[]

        官网资料:https://legacy.cplusplus.com/reference/string/string/operator[]/

        经过对于操作符 [ ] 的重载,string类对象也可以像C字符串那样访问和操作,这种遍历方案明显简单于迭代器,但缺点就是不通用,链表和树中无法用这种方案遍历。

                

        我们看官网上对于这个运算符的重载声明:

        首先,返回值是一个引用,这是为了可以对字符串中提取出来的某个字符进行修改(第一行的声明)。

        第二,它重载了两个,一个是正常的,另一个带了const修饰,这是为了防止在使用 [ ] 操作一个const string类型的字符串时,用第一种重载就会出现权限放大的问题,所以用const修饰了this指针指向的内容,和重载函数的返回值。

 PS: 范围for遍历(C++11)

        说到遍历,我们前面还提过一种范围for的遍历方案,自动++,自动判断结束。

        范围for遍历所有容器都可以用,因为范围for的底层就是迭代器,但范围for每次拿出来的这个e还是s1中一次一次正在遍历的字符的拷贝,如果 auto& 加上引用之后就可以修改s1了。

                

2.2.3.2 at访问

        at访问与方括号[ ] 访问的区别在于,at越界会抛异常,而[ ]会断言。抛异常后面的章节会讲到,这个是可以更改的,但是断言报错就直接崩掉程序了。

2.2.3.3 begin end 与 迭代器 

        begin:任何容器中都是返回第一个数据位置的 iterator(迭代器)

        end:任何容器中都是返回最后一个有效数据下一个位置的 iterator(迭代器)

        iterator(迭代器):可以理解成一个类似指针的东西,由它来控制目前访问的是第几号数据。之前我们学过访问数组中的某号元素时,是用下标来控制,但是这种 下标引用操作符 [ ] 的使用是有限制的,只能作用于顺序表。但是迭代器就比较通用,可以作用于顺序表,也可以作用于链表或树。

        不同容器的迭代器的实现是不尽相同的,所以 iterator 存在于各个容器的类域中,所以使用时要带上类域,否则全局范围内是找不到这个迭代器的。

                        

        因为 \0 不属于有效字符,算是一种标志,所以end返回的迭代器指向的位置就是 \0 而不是 \0 的下一个位置。

        可以看到再使用迭代器的时候我们用 * 来修改迭代器指向的内容的,其实这里是重载了 * 操作符,使得迭代器用起来更像指针。其他容器也是这么用 * 修改迭代器内容的。

        如果 s1 是const修饰的只读字符串,那么迭代器就要写成与其匹配的只读迭代器 const_iterator 防止权限放大。

                        

2.2.3.4 rbegin rend 与 反向迭代器

        这个就是把正向迭代器的所有用法反过来而已

        rbegn:返回最后一个有效数据的迭代器

        rend:返回第一个有效数据的前一位置的迭代器

        reverse_iterator:反向迭代器,++向前走,反向迭代器也有const版本

                        

PS: 算法排序 sort

        讲到迭代器就要提及sort算法,它是用来给各种容器内的数据排序的,默认是从小到大

        官网资料:sort - C++ Reference

        使用 sort() 要包含头文件 <algorithm> (算法),因为sort要给各类容器排序所以它是用模板写的,传的参数就是容器的迭代器,用两个迭代器来画出一块 左闭右开 的区域,此时sort就会在这块区域中排序了

                                ​​​​​​​

2.2.4 string类对象的修改操作

2.2.4.1 push_back append 与 operator+=

        push_back: string::push_back - C++ Reference

        append: string::append - C++ Reference

        operator+=: string::operator+= - C++ Reference

        push_back() 一次只能在string类对象后面添加一个字符。append()可以添加字符串、另一个string的实例化、用下标圈出来或用迭代器圈出来的另一个string等等,总之构造时能实现的所有方案它都能实现,不过那个是构造,但append是添加。

        但是上面两种都很少使用,operator+=操作符重载多方便啊,可以添加字符,字符串,或另一个string对象。

                ​​​​​​​        

2.2.4.2 pop_back 与 erase

        pop_back: string::pop_back - C++ Reference

        erease: string::erase - C++ Reference

        pop_back还是一次只能尾删一个字符,不太好用,它存在的意义就是和其他容器保持一致。

        erease可以通过 下标 和 元素个数 来进行删除,也可以通过迭代器但是用的比较少,注意迭代区间永远是左闭右开

        ​​​​​​​        ​​​​​​​        

2.2.4.3 assign 重新赋值

        官网资料:string::assign - C++ Reference

        这个成员函数的功能就是将string对象中的原有内容都删掉然后放入新内容,参数用法和构造的用法完全一样,唯一的区别就是不能修改成空string,而构造可以构造空string。

        

2.2.4.4 insert 插入

        官网资料:string::insert - C++ Reference

        前面的 += 操作符重载为我们提供了给string实例尾插的方法,那么insert就提供了在string实例的任意位置插入的方法。

        pos位置,用来选择在哪个位置插入,iterator迭代器也可以选择插入的位置。插入的内容可以是 char* 这种以 \0 结尾的C语言风格的字符串,也可以是C++的string类。        

        唯一要注意的是要插入一个字符的时候,用 5 号重载,插入一个字符时要给 n 传参为1,表示要插入 1 个字符。不能像传字符串那样,丢一串字符串就完事了,不去给字符数量。

                        

2.2.4.5 replace 替换

        官网资料:string::replace - C++ Reference

        别看这玩意一大堆,其实就是让你指出string中的一块地方,可以把这块地方的内容替换成别的内容而已,只是给出的替换方案相当多。

        ​​​​​​​        ​​​​​​​        

2.2.5 string类的其他操作

2.2.5.1 c_str 获取字符串指针

        可能之后写代码的时候C和C++混用,但是C没有string类,所以我们就获取字符转的底层指针,用来写C的代码段。

2.2.5.2 find 与 substr

        官网资料:string::find - C++ Reference

        find接口的功能是从 pos 位置向后找字符 c ,返回该字符在字符串中的下标

        find接口一般与substr接口一起使用,用于取下来字符串中用分隔符分隔开的某串字符串

        官网资料:string::substr - C++ Reference

        substr接口从 pos 位置开始,向后截取 len 个字符,然后将其返回

        ​​​​​​​   

2.2.5.3 operator+

        之前的operator+=只能支持基础string在前,后面加上一个string、char*或char。

        但是operator+的出现满足了基础string可以在后

                        

2.2.5.3 getline

        官网资料:getline (string) - C++ Reference

        cin与scanf一样,遇到空格或者换行都会认为是结束标志,于是就停止提取了,那如何获取一句带有空格的一句话呢?

        在C的时候我们会使用到 fgets 那么在C++的话我们就会用到getlin,同时getline还允许我们自己设置提取结束符 delim

        ​​​​​​​        ​​​​​​​        

        可以看到getline不会像fgets那样从前向后覆盖字符串,而是先清空string再获取新字符串。

        

2.2.5.4 to_string 与 stoi

        官网资料:to_string - C++ Reference

        to_string可以将各种数值转化成string,其功能类似于C库中的 itoa

        官网资料:stoi - C++ Reference

        stoi可以将string转化成整形,其功能类似于C库中的 atoi

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 语法 (杂七杂八的知识)

面向对象三大特性 封装, 多态, 继承 基本数据类型 一字节 (Byte) 占八位 (bit) JDK, JRE, JVM JDK (Java Development Kit) : Java 开发工具包, 包括了 JRE, 编译器 javac, 和调试工具 Jconsole, jstack 等 JRE (Java Runtime Environment) : Java 运行时环境, 包括了 JVM , …

【牛客】Tokitsukaze and Average of Substring

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和。 开一个int类型的前缀和数组pre[30][N]&#xff08;pre[i][j]表示某字符转成的数字 i 在一段区间的前缀个数。因为字母表有‘a’~z…

【使用ChatGPT的API之前】OpenAI API提供的可用模型

文章目录 一. ChatGPT基本概念二. OpenAI API提供的可用模型1. InstructGPT2. ChatGPT3. GPT-4 三. 在OpenAI Playground中使用GPT模型-ing 在使用GPT-4和ChatGPT的API集成到Python应用程序之前&#xff0c;我们先了解ChatGPT的基本概念&#xff0c;与OpenAI API提供的可用模型…

云原生Kubernetes: K8S 1.29版本 部署Harbor

目录 一、实验 1.环境 2.Linux 部署docker compose 3.证书秘钥配置 4.K8S 1.29版本 部署Harbor 5.K8S 1.29版本 使用Harbor 二、问题 1.docker 登录harbor失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构版本IP备注masterK8S master节点1.2…

java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条

今天遇到一个问题 系统线上问题&#xff0c;经常出现这样的问题&#xff0c;刚重启系统时不报错了&#xff0c;可是运行一段时间又会出现。sql已经写了limit 1&#xff0c;mybatis的debug日志也返回total为1&#xff0c;可是却报错返回了1805条数据 乍一看&#xff0c;感觉太不…

基于Spring Boot的公司OA系统设计与实现

基于Spring Boot的银行OA系统设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 用户登录界面&#xff0c;在银行OA系统运行后&#x…

基于springboot+jsp+Mysql的商务安全邮箱邮件收发

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

STM32单片机实战开发笔记-PWM波输出频率及占空比配置【wulianjishu666】

单片机物联网开发资料&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1XzodQuML7CqZ4ZKinDGKkg?pwdbgep 提取码&#xff1a;bgep PWM模块测试 功能描述 脉冲宽度调制模式&#xff1a; PWM边沿对齐模式&#xff1a; 向上计数配置 当TIMX_CR1寄存器中的DIR为低的时…

基于Python的LSTM网络实现单特征预测回归任务(TensorFlow)

单特征&#xff1a;数据集中只包含2列&#xff0c;时间列价格列&#xff0c;仅利用价格来预测价格 目录 一、数据集 二、任务目标 三、代码实现 1、从本地路径中读取数据文件 2、数据归一化 3、创建配置类&#xff0c;将LSTM的各个超参数声明为变量&#xff0c;便于后续…

php开发-个人博客项目文件操作类编辑器上传下载删除读写

特地整了个软件 这就舒服了 文件操作类的开发 文件的任意上传&#xff0c;下载&#xff0c;读取&#xff0c;删除操作等 1.文件上传类-任意文件上传 分为三类 1&#xff0c;代码自主编写的 先写一个html的上传表单&#xff0c;这个网上搜索就有 标题看着不够明确啊&#…

【牛客】【模板】差分

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 差分模板。 b[0]a[0]; b[1]a[1]-a[0]; b[2]a[2]-a[1]; ...... b[n-1]a[n-1]-a[n-2]; b[n]a[n]-a[n-1]; 差分标记&#xff1a;b[l]k,b…

计算机网络chapter1——家庭作业

文章目录 复习题1.1节&#xff08;1&#xff09; “主机”和“端系统”之间有何不同&#xff1f;列举几种不同类型的端系统。web服务器是一种端系统吗&#xff1f;&#xff08;2&#xff09;协议一词常用来用来描述外交关系&#xff0c;维基百科是如何描述外交关系的&#xff1…

基于Springboot的校园悬赏任务平台(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园悬赏任务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

Codigger:Web应用让开发者拥有更高效的开发之旅

在当今软件开发领域&#xff0c;Web应用以其跨平台、易访问和实时更新的特性&#xff0c;逐渐成为了主流的开发方向。从开发者的视角来看&#xff0c;Codigger借助B/S&#xff08;浏览器/服务器&#xff09;架构和云计算技术&#xff0c;为开发者带来了诸多便利和优势。这些优势…

【负载均衡式在线OJ项目day1】项目结构

一.功能 查看题目列表&#xff0c;在线编程&#xff0c;判题功能&#xff0c;即leetcode的部分功能 二.宏观结构 整个项目是BS模式&#xff0c;客户端是浏览器&#xff0c;和用户交互并向服务器发起请求。 服务端从功能上来说分为两个模块&#xff0c;第一个是OJServer&…

C++ 多态(一)

一、多态定义 同一种操作作用于不同的对象时&#xff0c;可以产生不同的行为。在面向对象编程中&#xff0c;多态性是指通过继承和重写实现的&#xff0c;同一个方法在不同的子类中可以表现出不同的行为。多态性可以提高代码的灵活性和可扩展性&#xff0c;使得程序更易于维护…

盘点企业信息防泄密软件对比|揭秘企业信息防泄密软件好用榜

在当今信息化社会&#xff0c;企业信息防泄密软件的需求日益凸显。这些软件不仅关乎企业的核心竞争力&#xff0c;更直接关系到企业的生死存亡。本文将对市面上几款主流的企业信息防泄密软件进行深入对比分析&#xff0c;以期为企业提供有益的参考。 一、企业信息防泄密软件好…

987: 输出用先序遍历创建的二叉树是否为完全二叉树的判定结果

解法&#xff1a; 一棵二叉树是完全二叉树的条件是&#xff1a; 对于任意一个结点&#xff0c;如果它有右子树而没有左子树&#xff0c;则这棵树不是完全二叉树。 如果一个结点有左子树但是没有右子树&#xff0c;则这个结点之后的所有结点都必须是叶子结点。 如果满足以上条…

docker学习笔记(三)搭建NFS服务实验

目录 什么是NFS 简单架构​编辑 一.搭建nfs服务器 二.新建共享目录和网页文件 三.设置共享目录 四&#xff1a;创建使用nfs共享目录的卷 五&#xff1a;创建容器使用nfs-web-1卷 六&#xff1a;测试访问 七&#xff1a;是否同步测试 什么是NFS NFS 服务器&#xff1a;ne…

webpack如何自定义一个loader

我们在使用脚手架的搭建项目的时候往往都会帮我们配置好所需的loader&#xff0c;接下来讲一下我们要如何自己写一个loader应用到项目中&#xff08;完整代码在最后&#xff09; 1. 首先搭建一个项目并找到webpack配置文件&#xff08;webpack.config.js&#xff09; 在modul…