【C++】string类的使用

news2024/11/25 9:38:07

目录

一、标准库中的string类

二、string类的常用接口

1、string类对象的常见构造

2、string类对象的容量操作

2.1、size 与 length

2.2、capacity 与 reserve

2.3、resize

2.4、总结

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

3.1、operator[] 与 at

3.2、begin + end

3.3、rbegin + rend

3.4、 const类型迭代器

3.5、范围for

4. string类对象的修改操作

4.1、push_back、append、operator+=

4.2、insert 与 erase

4.3、find 与 replace

4.4、substr 与 rfind

4.5、c_str

4.6、find_first_of 与 find_last_of

5、string类非成员函数

5.1、getline


一、标准库中的string类

string类是由模板 basic_string 显示实例化为 char 类型得到的类,并用关键字 typedef 命名为 string

 当模板参数是 char 时,类名为 string ,与之相对的,还有其他各种各样由模板 basic_string 显示实例化的到的类名,比如:wstring、u16string、u32string等

 wstring 类管理的是 wchar_t 类型的字符,一个字符占据个字节。

 u16string 类管理的是 char16_t 类型的字符,一个字符占据个字节。

 u32string 类管理的是 char32_t 类型的字符,一个字符占据 4 个字节。


之所以要区分出这么多字符类,是为了满足各种各样不同的需求,比如编码的需求。

 以 ascll 码为例,ascll码的出现是为了更好的表示英文,算上26个字母、10个数字以及各种各样的符号、控制字符等等,只需要 128 个字符的映射表就能满足几乎所有的表示需求。

但是对于中文、甚至是更加复杂的文字而言,128个字符的映射表就已经没有办法满足需求了,就需要更多字符的映射表,自然也需要占据更多字节大小的空间。

为了更好的满足这一需求,就出现了另一个编码规则:Unicode,即统一码。统一码又分为 3 种,分别为 UTF-8、UTF-16、UTF-32。

UTF-8兼容ascll码,对不同范围的字符使用不同长度的编码,也是我们最常用的编码方式。

 对于0x00-0x7F之间的字符,UTF-8编码与ascll编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。统一码的最大码位0x10FFFF也只有21位。UTF-8 编码以二进制数字的前缀来区分一个字符占据几个字节

其中类 string 所对应的编码方式就是 UFT-8

 我们来举个例子具体说明一下:

 str1 中存储的是英文字母,使用 ascll 码即可表示(一个字符占据一个字节),例如 'h' 的值为十进制 104 ,换算到八位二进制为 01101000 前缀为零

 str2 中存储的是中文字符,一个字符占据两个字节,所以这两个字节的二进制数前缀分别为 110 10。转换成十进制表现为两个负数。两个中文字符就是四个字节,加上最后的 '\0' 为五个字节大小。

通过更改中文字符的数值,我们可以观察到中文字符编码的规律是把同音字编在一起的:

二、string类的常用接口

1、string类对象的常见构造

(constructor)函数名称功能说明
string()构造空的string类对象,即空字符串
string(const char* s)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string& s)拷贝构造函数
string (const string& str, size_t pos, size_t len = npos)拷贝从字符串第 pos 个字符开始向后的 npos 个字符

例如:

 对于 string (const string& str, size_t pos, size_t len = npos) ,库中提供了一些额外的解释,如果 npos 的大小超出了字符串的有效长度范围,就自动取到字符串中最后一个有效字符为止。如果没有指定 npos 的值,就使用缺省参数 -1 ,由于 size_t 是无符号整型,所以 -1 实际上是二进制的全一,即最大的整型数值 2^32 - 1

2、string类对象的容量操作

函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty (重点)检测字符串是否为空串,是返回true,否则返回false
clear (重点)清空有效字符
reserve (重点)为字符串预留空间**
resize (重点)将有效字符的个数改成n个,多出的空间用字符c填充

2.1、size 与 length

 size length 都是返回字符串的有效字符长度,用法如下:

 功能完全相同,只是为了名字与 stl 中其他模板的名称保持一致,就增加了一个 size ,除了名字不同外,没有区别。

2.2、capacity 与 reserve

 capacity 返回空间总大小,用于观察开辟空间的情况:

 当不断向string对象 s 中尾插字符时,会导致 s 不断的扩容,可以发现除了第一次扩容外,其他扩容后的大小都是上一次的 1.5 倍。

 string 对象第一次扩容的规则大致如下:

 类string中有一个容量为 16 个字符的数组 buf ,如果对象中存储的字符数量小于等于 16 个,就会把字符存入数组 buf 中,不使用指针 _ptr 。如果对象中存储的字符数量大于 16 个,就会使用指针 _ptr 来开辟空间,第一次直接开辟 32 个字符的空间,并把字符存放在新开辟的空间中, buf 不再使用。之后每次开辟的空间大小是开辟之前大小的 1.5 倍。

这种规则只适用于VS编译器,不同的编译器有不同的扩容规则。

为了防止编译器不断的给 string 对象扩容空间,造成资源的浪费,我们可以使用 reserve 直接给对象预留一定大小的空间:

 其中因为一些内存对齐等原因,实际内存空间与我们设定的有一些出入,但一定不会比我们设置的小。

2.3、resize

 resize 将有效字符的个数改成 n 个,多出的空间用字符c填充。 resize 可以扩容空间,并进行初始值填充:

可以看到 resize reserve 不同。使用 resize 进行扩容的时候,也进行了字符填充,使对象的有效字符长度也发生了变化。

 在vs编译器中,默认填充的字符是 '\0'

我们也可以指定填充的字符,写成如下形式:

 如果指定的 n 值比 size 小,则会删除数据,保留前 n 个:

 size 变为 5 capacity 的值不变。 

2.4、总结

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

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

函数名称功能说明
operator[]返回pos位置的字符,const string类对象调用
begin+ endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭
代器
rbegin + rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭
代器
范围forC++11支持更简洁的范围for的新遍历方式

3.1、operator[] 与 at

 operator[] 返回pos位置的字符,是一个运算符重载,关于运算符重载的内容,在《类和对象(二)》里有过详细的说明。

 at 的作用与 [] 类似,都是获取指定下标的数据,只不过在越界的处理方面有些不同。如果 [] 中的下标越界,程序会直接发生断言错误,终止程序,而如果 at 指向的下标越界,则会进行抛异常。

3.2、begin + end

我们想要打印一个数组,除了使用运算符重载 [] 外,还可以使用 begin end 获取迭代器。具体用法如下:

 关于迭代器,大家暂时可以先理解为指针, begin 是第一个位置的指针, end 是最后一个位置的下一个位置的指针。

3.3、rbegin + rend

 rbegin rend 获取的是反向迭代器,目前阶段同样可以先把他们看作指针,其中 rbegin 指向最后一个数据的位置, rend 指向第一个位置的前一个位置:

 用法如下:

3.4、 const类型迭代器

当使用 const 类型来接收string类对象时,如果直接使用关键字 interator 来定义迭代器变量,编译器会报错。

 所以为了保证权限不被放大,需要使用关键字 const_iterator 来定义迭代器变量:

3.5、范围for

打印一个数组,还有另一种方法,就是使用 范围for ,具体用法如下:

 实际上,范围for的底层就是使用迭代器来实现的。

4. string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+= (重点)在字符串后追加字符串str
c_str(重点)返回C格式字符串
find(重点)从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
replace替换字符串pos位置,len长度的字符
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回
insert在str中插入字符
erase在str中删除字符
find_first_of找到其中任意一个字符,并返回其位置
find_last_of

4.1、push_back、append、operator+=

 push_back 在字符串尾部插入字符,具体用法如下:

 append 在字符串尾部插入字符串,具体用法如下:

 相比较于以上两种接口,最简单且最常用的其实是 operator+= ,具体用法如下:

4.2、insert 与 erase

 insert :在字符串的 pos 位置插入字符串或者 n 个字符。

比如在字符串 "world" 的第 0 个位置插入字符串 "hello"

在字符串 "helloworld" 5 个位置插入 1 个字符 ' ' : 

  erase :在字符串的 pos 位置删除 n 个字符。

例如,在字符串 "hello world" 的第 6 个位置删除 1 个字符:

 如果指定的 n 超出了字符串的有效范围,或者不指定 n 的值,就删除到字符串最后的位置。

 

 注意 insert erase 不推荐经常使用,因为他们可能都要挪动数据,效率低下。

4.3、find 与 replace

 find :从字符串的 pos 位置向后寻找指定字符,返回该字符在字符串中的位置,如果没有指定 pos 的值,就使用缺省参数 0 。如果字符串中没有找到指定字符,就返回 npos ,即无符号整型 -1

例如,找到字符串 "hello world" ' ' 的位置:

 找到字符串 "hello world i love you" 中第二个 ' ' 的位置:

 replace :替换字符串 pos 位置, len 长度的字符。

例如,把字符串 "hello world i love you" 中所有的 ' ' 都替换为 "%20"

 这样每次使用 replace 来替换字符,都会扩容空间,为了提高效率,我们可以使用 reserve 来提前开辟空间:

4.4、substr 与 rfind

 substr :在str中从 pos 位置开始,截取 n 个字符,然后将其返回。

例如:打印字符串 "string.cpp" 的后缀:

如果我们不指定 n 的值,就使用缺省参数 npos ,即无符号整型 -1 。 不指定 pos 的值,就是用缺省参数 0

不过也有时,文件的名字中存在多个字符 '.' , 为了寻找文件真正的后缀,我们需要找到最后一个 '.' 的位置。可以使用 rfind :从字符串pos位置开始往前找指定字符,返回该字符所在的位置:

4.5、c_str

 c_str 返回C格式字符串。

打印字符串有如下两种方式:

 其中第一种,s 是自定义类型, "<<" 是自定义类型重载的流插入。第二种 s.c_str() 返回的是C格式字符串的指针,类型为 char* "<<" 是库里面的流插入。如果把 s.c_str() 返回的指针强转成其他类型,就会打印出指针,而不是字符串:

 如果把字符串进行以下处理后,这两种打印方式得到的结果是不同的:

 可知,如果我们使用流插入来打印string对象,会以 size 的大小来打印,不会关注 '\0' 。而使用流插入来打印 char* 类型的指针,就会打印到 '\0' 后结束。

4.6、find_first_of 与 find_last_of

 find_first_of  :在字符串中,从前往后找到其中任意一个字符,并返回其位置。

例如,把一段字符串中所有的 'a'、'b'、'c'、'd' 都替换为 '*'

 find_last_of :在字符串中,从后往前找到其中任意一个字符,并返回其位置。

5、string类非成员函数

函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>>输入运算符重载
operator<<输出运算符重载
getline (重点)获取一行字符串
relational operators大小比较

5.1、getline

 当我们使用 cin 来提取字符串时,字符串中不能含有空格,因为 cin 在遇到空格、'\n' 等字符时,会默认提取结束。

为了解决这个问题,我们可以使用 getline

int main()
{
	string str;
	//cin >> str;
	getline(cin, str);

	return 0;
}

关于string类的使用相关内容就讲到这里,希望同学们多多支持,如果有不对的地方欢迎大佬指正,谢谢!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Portraiture5人像磨皮润色修饰插件

Portraiture3和Portraiture4这两个版本大家用的比较多&#xff0c;那是因为这两个版本是中文比较全的版本。portraiture是一款强大的64位PS磨皮滤镜&#xff0c;利用该PS滤镜插件可以对图片中的人物进行润色&#xff0c;磨皮等操作&#xff0c;处理皮肤材质、头发等。帮您消除了…

HNU工训中心:平台 2HDL 语言与验证实验报告

一、自定 FSM 说明 1、状态描述 State0&#xff1a;睡觉&#xff0c;如果闹钟响则起床吃早餐&#xff0c;否则继续睡觉 State1&#xff1a;吃早餐&#xff0c;吃完去上课 State2&#xff1a;上课&#xff0c;上完课后如果要开会就去开会&#xff0c;否则去自习 State3&…

LiveGBS国标GB/T28181视频流媒体平台-功能视频集中录制存储云端录像H264|H265|HEVC视频存储

LiveGBS国标GB/T28181视频流媒体平台-视频集中录制存储云端录像H264|H265|HEVC视频存储1、云端录像存储2、手动配置录像2.1、按需录像2.2、一直录像3、录像计划3.1、录像计划入口3.2、新增录像计划3.3、编辑录像计划3.4、关联通道4、查看云端录像4.1、查看录像4.1.1、时间轴模式…

vue路由文件拆分管理

随着项目的原来越大&#xff0c;路由越来越多&#xff0c;我们的路由也会越来越多&#xff0c;如果都集中在一个文件中&#xff0c;会很冗杂文件很长。这时候我们可以将路由文件拆分&#xff0c;可读、方便管理。多人合作添加路由也能更多的避免代码冲突 代码拆分目录如图&…

18 客户端服务发现源码分析

Nacos客户端服务发现源码分析 总体流程 首先我们先通过一个图来直观的看一下&#xff0c;Nacos客户端的服务发现&#xff0c;其实就是封装参数、调用服务接口、获得返回实例列表。 但是如果我们要是细化这个流程&#xff0c;会发现不仅包括了通过NamingService获取服务列表&…

运筹系列79:使用Julia进行column generation求解

1. 案例建模 我们对cutting stock问题进行建模。rolls的尺寸为W&#xff0c;每个型号的需求量和尺寸分别为d和w&#xff0c;如下&#xff1a; struct Piecew::Float64d::Int endstruct Datapieces::Vector{Piece}W::Float64 endfunction Base.show(io::IO, d::Data)println(i…

hls.js如何播放m3u8文件(实例)?

HLS&#xff08;HTTP Live Streaming&#xff09;是一种视频流传输协议&#xff0c;是苹果推出的适用于iOS与macOS平台的流媒体传输协议。它将视频分割成若干个小段&#xff0c;每个小段大小一般为2~10秒不等&#xff0c;并通过HTTP协议进行传输。通过在每个小段之间插入若干秒…

C++学习笔记-多线程

传统的C&#xff08;C11之前&#xff09;中并没有引入线程这个概念&#xff0c;在C11出来之前&#xff0c;如果我们想要在C中实现多线程&#xff0c;需要借助操作系统平台提供的API&#xff0c;比如Linux的<pthread.h>&#xff0c;或者windows下的<windows.h> 。 …

数据结构——链表讲解(1)

作者&#xff1a;几冬雪来 时间&#xff1a;2023年3月3日 内容&#xff1a;数据结构链表讲解 目录 前言&#xff1a; 链表的概念&#xff1a; 1.为什么要有链表&#xff1a; 2.链表的运行原理&#xff1a; 3.链表的形态多少&#xff1a; 4.单链表的代码书写&#xff1…

QML定时器

QML使用Timer使用定时器 Timer 计时器可用于触发操作一次&#xff0c;或以给定的间隔重复触发。 常用属性&#xff1a; interval 设置触发器之间的间隔&#xff08;以毫秒为单位&#xff09;。 默认间隔为 1000 毫秒。 repeat 设置重复&#xff0c;为真&#xff0c;则以指定的…

【力扣】stack容器的探索之有效的括号

作者&#xff1a;狮子也疯狂 专栏&#xff1a;《算法详解》 愿你生如夏花之绚烂&#xff0c;幸运永远与你相伴&#xff0c;疯狂常在。 目录一. &#x1f981; Stack容器的来历1.1 操作栈的方法二. &#x1f981; Stack的使用2.1 题目2.2 分析2.3 详细算法实现2.4 力扣AC截图三…

vscode与C++安装与使用【不好用来骂我】

网上教程很多&#xff0c;但是都不太好用&#xff0c;这是我垃圾堆里淘金淘出来的教程&#xff1a; 安装软件 安装 Visual Studio Code: 你需要下载并安装 Visual Studio Code&#xff0c;可以在官网下载 https://code.visualstudio.com/download。 安装 C 扩展: 在 Visual S…

【基础算法】单链表的OJ练习(2) # 链表的中间结点 # 链表中倒数第k个结点 #

文章目录前言链表的中间结点链表中倒数第k个结点写在最后前言 对于单链表的OJ练习&#xff0c;需要深刻理解做题的思路&#xff0c;这样我们才能够在任何场景都能够熟练的解答有关链表的问题。 关于OJ练习&#xff08;1&#xff09;&#xff1a;-> 传送门 <-&#xff0c…

支持向量机简单介绍

1.概述 支持向量机&#xff08;SVM&#xff0c;支持向量网络&#xff09;&#xff0c;是机器学习中获得关注最多的算法没有之一。它源于统计学习理论。 | | | 功能有监督学习线性二分类与多分类&#xff08;Linear Support Vector Classification&#xff09;非线性二分类与多…

你真的会用三元运算符吗?

在我们日常搬砖中&#xff0c;我们经常会看到三元运算符&#xff0c;但是你了解三元运算符到底是怎么用吗&#xff1f;接下来我们就下来详细介绍一下三元运算符大厂面试题分享 面试题库前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#x…

职场人必备的6款实用办公app,每一款都是心头爱

打工人不容易啊&#xff0c;不提高工作效率怕是要被淘汰了。今天给大家分享6款职场人必备的实用办公APP&#xff0c;免费效率神器让工作事半功倍。这些APP每一款都是我的心头爱&#xff0c;肯定会让人大开眼界的&#xff0c;超级实用&#xff0c;直接往下看吧。1、向日葵远程控…

docker前端开发环境搭建

docker 做本地开发环境的好处&#xff1a; 隔离环境 各项目所需node等版本不一&#xff0c;切换起来比较麻烦&#xff0c;虽用 nvm可 来解决&#xff0c;但使用 docker 更优 快速配置环境 新电脑&#xff0c;新系统&#xff0c;新环境&#xff0c;第一件事就是配置开发环境。下…

[Java代码审计]—MCMS

环境搭建 MCMS 5.2.4&#xff1a;https://gitee.com/mingSoft/MCMS/tree/5.2.4/利用 idea 打开项目 创建数据库 mcms&#xff0c;导入 doc/mcms-5.2.8.sql 修改 src/main/resources/application-dev.yml 中关于数据库设置参数 启动项目登录后台 http://localhost:8080/ms/l…

【NLP】自动化计算文本文件TTR的bash脚本

自动化计算文本文件TTR的bash脚本 简介 这是一个可以计算文本文件TTR的bash脚本&#xff0c;文件名为&#xff1a;calculate_TTR.sh。它会接收一个文件名作为参数&#xff0c;并输出总单词数、特异单词数和TTR。 TTR是什么 TTR&#xff08;Type-Token Ratio&#xff09;是用…

javaweb期末复习重点

2022.12.12javaweb复习重点 10个选择题10个填空题10个判断2-3简答题2个程序题&#xff08;15分一个&#xff09; 1.HTML、Javascript、divcss ? 详细解释 HTML HTML(Hyper Text Mark-up Language)即超文本标记语言&#xff0c;是用于描述网页的一种标记语言。简单来说&…