C++ [STL之string的使用]

news2025/1/11 7:44:51

标题图

本文已收录至《C++语言和高级数据结构》专栏!
作者:ARMCSKGT

在这里插入图片描述


文章目录

  • 前言
  • 正文
    • 编码
    • basic_string类
      • 说明
      • basic_string实例成员
      • 关于string
    • string类模块
      • 构造函数
      • 空间大小相关
        • 字符串长度及容量大小
        • 清空字符串和空串查询
        • 字符串大小和容量设置
      • 访问与遍历
        • 头尾元素及字符串指针
        • 下标遍历
        • 迭代器
      • 字符串插入与删除
        • 字符串插入
        • 删除字符串
      • 查找
      • 其他功能性函数
        • 替换replace
        • 交换swap
        • 截取字符串substr
        • 字符串比较函数compare
      • 非成员函数
        • 输入输出流
        • 获取一行字符串(包括空格)
        • 比较运算符重载
        • operator **+** 运算符
  • 最后

前言

字符串在程序中经常出现,C语言为此提供了很多字符串操作函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问,于是STL单独为字符串实现了一个容器,用来专门存储操作字符串,本文将介绍string的常用接口,有了string的加入,我们对字符串的操作将游刃有余!


正文

编码


我们知道计算机是美国最先研究的,为了描述字符出台ASCII((American Standard Code for Information Interchange)美国信息交换标准代码)编码,在计算机存储和显示英文信息,是美国标准,ASCII仅需 1Byte 就能存储,所以计算机中字符类型为1字节。


而我们现在最常用的是UTF-8标准,UTF-8标准兼容ASCII,在计算机中广泛使用!UTF-8最大的特点是根据不同范围的字符匹配使用不同的标准,因为ASCII 都是 0x??? 的形式,当识别到其他字符时,会匹配使用对应标准,比如当识别到汉字时,会使用 GBK 编码标准来进行输出(Windows)。

随着计算机的普及,越来越多的国家开始使用计算机,于是为了兼容几乎所有国家,出台了Unicode(中文又称万国码、国际码),提出了能适用更多语言的编码标准,即 UTF-16 和 UTF-32。,Unicode是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。


basic_string类


说明

  1. 字符串是表示字符序列的类。
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string))。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数。
  5. 这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

basic_string实例成员

  • string
    表示字符串的字符串类(本文主讲对象)。
  • wstring
    表示宽字符的字符串类,用来处理较长的字符串,在Windows下占2字节,Linux下占4字节。
  • u16string(C++11)
    匹配UTF-16标准,字符占位2字节。
  • u32string(C++11)
    匹配UTF-32标准,字符占位4字节。

    之所以有这么多basic_string字符串实例版本是为了适应不同国家语言字符串,而我们常用的是string类。

关于string

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  4. 不能操作多字节或者变长字符的序列。
  5. 在使用string类时,必须包含#include< string >头文件以及using namespace std(或using std::string)。

string类模块


构造函数

构造函数功能
string()默认构造函数
string (const string& str)拷贝构造函数
string (const string& str, size_t pos, size_t len = npos)从str中pos位置开始拷贝len个字符进行构造(默认将pos后的字符的全部拷贝,如果不足len个则也是全部拷贝)
string (const char* s)通过字符串s构造
string (const char* s, size_t n)从字符串s中拷贝n个字符构造
string (size_t n, char c)构造n个c字符组成的字符串
string (InputIterator first, InputIterator last)迭代器区间构造(迭代器介绍在后面)
//代码演示
#include <iostream>
using namespace std;
#include <string>

int main()
{
	const char* s = "ABCDEFGHIJKL\0";
	string s1; //默认构造
	string s2(s); //通过字符串s构造
	string s3(s2); //拷贝构造
	string s4(s3,2,5); //选择拷贝构造,从s3的2下标位置拷贝5个字符
	string s5(s, 5); //取s字符串中前五个字符构造
	string s6(10, 'a'); //10个字符a构造

	//迭代器区间构造(左闭右开区间)
	string s7(s, s + 12); //支持指针(指针也算是迭代器)
	string s8(s2.begin(), s2.end()); //通过容器迭代器构造(适用于所有支持迭代器的容器)

	return 0;
}

运行结果



空间大小相关

字符串长度及容量大小

  • size() 字符串大小
  • length() 字符串大小
    size与length几乎没区别,但是因为string是先于STL诞生的,后来为了统一于其他容器,增加了size,在使用时,主要以size为主!
  • capacity() 容量大小
    演示

清空字符串和空串查询

  • clear() 清空字符串(非释放对象)
  • empty() 查询字符串是否为空(空返回真)

字符串大小和容量设置

  • resize 设置字符串长度
    resize有两种调用方式,构成重载

    1.第一种是resize(size_t n) 将字符串设置为n,如果n小于当前字符串长度,则字符串长度缩小至n,如果大于n则字符串长度为n,增长的字符位初始化为0
    2.第二种是resize(size_t n,char c) 将字符串长度增长至n,如果n大于当前字符串长度,则增长的空间以字符c全部填充,如果低于字符串长度,则只修改字符串长度

    这里需要说明的是,如果resize的数量比当前容量大,则会进行扩容,但resize的数量比字符串小则只会抹除多余的字符,但并不会缩容,哪怕resize(0)也不会!
  • reserve(n) 设置容量为n
    我们可以手动设置字符串容量大小,以减小频繁扩容带来的性能损失! 虽然reserve可以设置容量,但是在VS平台下仍然不支持缩容,因为缩容的代价比扩容大,而且对于现代计算机来说这些少量空间没必要来回申请和释放!但如果我们在VS平台下reserve空间小于等于15时(在容量大于15的情况下),编译器会将前15个有效字符拷贝到缓冲区并释放申请的空间!在Linux平台下则是老老实实的缩容!

    这里要注意的是:
    VS的扩容策略是,VS预先有一个15字节大小的缓冲区,当我们的字符数量大于15时VS会开辟空间并通过指针管理,空间大小为30(第一次扩容为2倍),以后的每次扩容是1.5倍式增长,而且VS并不是稳定的按此算法去计算大小,每次都会多开一些空间。
    区别于VS,Linux下g++的string初识容量大小为0,扩容策略是第一次扩容为1,往后则是稳扎稳打的2倍式扩容,不会多开,而且可以缩容!


访问与遍历

头尾元素及字符串指针

  • front() 返回string中第一个字符
  • back() 返回string中最后一个字符
  • c_str() 返回字符串的指针类型
    string支持通过对象返回一个char类型指针指向字符串。

下标遍历

  • [ ] 下标访问
    string支持像访问数组一样访问字符串,越界会报错
  • at() 对象调用,下标访问
    功能与[ ]类似,但是at是通过对象调用且at下标越界时会抛异常

迭代器

迭代器成对出现,分别是 begin()指向第一个元素end()指向字符串末尾的下一个位置(即’\0’) ,所以迭代器是左闭又开区间;我们可以把迭代器想象成指针去使用,通过++/- -改变当前指向的元素位置,以及使用 " * " 解引用访问和修改,但迭代器本质不是指针

在使用迭代器时,不同容器有不同的迭代器且迭代器也分不同的类型,例如string的普通迭代器类型是 string::iterator 使用此类型定义一个迭代器并进行赋值!

获取容器迭代器只需要通过 类名::迭代器类型 即可定义迭代器!

  • 普通迭代器begin()与end()
    普通的迭代器支持的使用与指针没有区别
    普通迭代器类型定义:string::iterator
  • 反向迭代器rbegin()与rend()
    反向迭代器与普通迭代器不同点是,反向迭代器rbegin()指向字符串最后一个元素,rend()指向第一个元素的前一个位置(可以理解为-1),也是一个一闭一开区间,反向迭代器顾名思义,是倒着遍历的,++相当于普通迭代器的- -,其他的与普通迭代器相同
    反向迭代器类型定义: string::reverse_iterator
  • const迭代器cbegin()和cend()
    const迭代器类型定义: string::const_iterator
  • const反向迭代器crbegin()和crend()
    const反向迭代器类型定义: string::const_reverse_iterator

    const迭代器在原迭代器的基础上不能对迭代器所指向的元素进行修改,但是可以++/- -访问所有元素,在某些const传参的场景下会遇到

    虽然string有迭代器遍历,但是对于顺序性存储结构,大部分场景下还是使用 [ ] 下标遍历比较方便,所有支持迭代器的容器都支持范围for遍历元素


字符串插入与删除

字符串插入

  • push_back()
    push_back可以向字符串尾插一个字符
  • append()
    append的功能是在字符串尾部追加字符和字符串,而且有多种用法
    append有多个函数重载形式

    append的这些使用方法与前面构造函数的使用方式相似,有兴趣的小伙伴可以下去慢慢研究,不过最常用的是追加字符串!
  • operator += 运算符
    这个+=运算符的功能十分强大,是在尾部追加字符和字符串,在使用string时经常使用
  • operator = 运算符
    赋值运算符与平时使用一样,使用单个字符字符串直接覆盖原字符串!
  • insert
    insert支持任意位置插入字符串,插入依据既可以是下标也可以是迭代器
    insert也有许多重载形式

    不过,因为是任意位置插入,根据顺序表的性质,需要挪动元素,会有性能损失,一般按需使用!

删除字符串

  • erase
    erase支持任意位置删除,删除依据也是下标或迭代器
    erase也有三个重载版本
    –从pos位置开始删除len个字符(包括pos位置)
    –迭代器区间删除,删除first和last之间的字符串(左闭右开区间,删除范围从first开始,包括first,不包括last)


    这里要注意的是,与insert一样,顺序表删除元素是靠从后往前覆盖实现的,有一定的性能损失,一般情况下能少用就少用!

    关于npos
    这里要额外提一笔的是,npos在string中经常作为缺省参数出现,底层的机制是如果指定的操作长度大于字符串长度默认将此范围内一直到末尾的字符串全部进行操作,而npos是无符号整型-1,也就是整型的最大值,不过在不同平台,大小可能不同!


查找

  • find
    find有四种重载形式,也是查找字符串最常用的接函数> find只能使用下标进行查找,查找单个字符或字符串,在一个string中查找另一个string子串,返回的也是下标,如果没找到则返回npos(无符号整型的最大值),对于查找单个字符返回的是字符下标,查找字符串则是返回字符串首元素的下标!>
  • rfind
    rfind也有四个重载形式的函数,基本上与find保持一致,最大的特点是rfind是从后往前查找,反向遍历!
  • find_first_of
    这个函数比较特殊,查找字符串中出现的任意字符,默认pos位置是0(从头开始),可以指定起始查找位置,该函数有四种重载形式
  • find_last_of
    与find_first_of基本相似,只不过find_last_of是从后往前找
  • find_first_not_of
    与find_first_of类函数相反,在字符串中搜索与其参数中指定的任何字符不匹配的第一个字符
    该函数有四种重载形式
  • find_last_not_of
    与find_first_not_of相似,区别在于find_last_not_of是从后往前找


其他功能性函数

替换replace

replace
replace函数,可以替换字符串中一段,有多种重载形式


交换swap

swap
string内置了交换函数也支持库函数进行交换!


截取字符串substr

substr
substr支持从pos下标(默认为0)截取len个字符并重新构造一个string对象作为返回值


字符串比较函数compare

compare
string拥有一个比较函数compare,这个用的很少,因为没有运算符方便!



非成员函数

输入输出流

C++重载了operator <<>> 运算符,所以string类对象支持使用cin和cout进行流插入和流提取
这里需要注意的是cin流提取字符串时,是全覆盖式的写入字符串,cin输入字符串会覆盖以前的字符串!


获取一行字符串(包括空格)

getline函数支持一次截取一行字符串,碰到换行截至,这个函数在需要空格输入时非常实用!
其参数为cin和string对象


比较运算符重载

C++重载了字符串比较运算符,所以string拥有自己的比较规则


operator + 运算符

这个+**运算符比较特殊,将两个字符串拼接以一个新的string对象作为返回值


最后

string的使用介绍到这里就介绍了,可以发现前辈们为了能自由自在摆弄字符串也是煞费苦心,好在字符串的操作在string的加持下确实非常方便,本文介绍了大部分接口,但是并非全部常用,想要掌握string还得平时多用并结合 string文档 加以升华!

本次 <C++ string使用> 就先介绍到这里啦,希望能够尽可能帮助到大家。

如果文章中有瑕疵,还请各位大佬细心点评和留言,我将立即修补错误,谢谢!
在这里插入图片描述

🌟其他文章阅读推荐🌟
C++ <模板> -CSDN博客
C++ <内存管理> -CSDN博客
C++ <类和对象 - 下> -CSDN博客
C++ <类和对象 - 中> -CSDN博客
C++ <类和对象 - 上> -CSDN博客
🌹欢迎读者多多浏览多多支持!🌹

​​

​​


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

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

相关文章

探索【Stable-Diffusion WEBUI】的插件:界面与中文翻译

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;主题&#xff08;kitchen Theme&#xff09;&#xff08;二&#xff09;对照翻译&#xff08;Bilingual Localization&#xff09;&#xff08;三&#xff09;自行翻译&#xff08;四&#xff09;提示词翻译…

前端02:CSS选择器等基础知识

CSS基础选择器、设置字体样式、文本样式、CSS的三种引入方式、能使用Chrome调试工具调试样式 HTML专注做结构呈现&#xff0c;样式交给CSS&#xff0c;即结构&#xff08;HTML&#xff09;和样式CSS相分离 CSS主要由量分布构成&#xff0c;选择器以及一条或多条声明 选择器&…

华为OD机试真题(Java),喊7的次数重排(100%通过+复盘思路)

一、题目描述 喊7是一个传统的聚会游戏&#xff0c;N个人围成一圈&#xff0c;按顺时针从1到N编号。 编号为1的人从1开始喊数&#xff0c;下一个人喊的数字为上一个人的数字加1&#xff0c;但是当将要喊出来的数字是7的倍数或者数字本身含有7的话&#xff0c;不能把这个数字直…

ML之DR:基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例

ML之DR&#xff1a;基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例 目录 基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例 # 1、定义数据集 # 2、数…

华为OD机试真题(Java),密码验证合格程序(100%通过+复盘思路)

一、题目描述 密码要求: 长度超过8位包括大小写字母.数字.其它符号,以上四种至少三种不能有长度大于2的包含公共元素的子串重复 &#xff08;注&#xff1a;其他符号不含空格或换行&#xff09; 二、输入描述 一组字符串。 三、输出描述 如果符合要求输出&#xff1a;OK&…

Oxygen Content Fusion carck

Oxygen Content Fusion carck 输入法支持改进-对非拉丁语言输入法编辑器(IME)的支持在稳定性和性能方面得到了改进。 文件比较工具中环绕差异的精确显示-文件比较工具现在可以更好地识别和显示环绕编辑产生的差异。例如&#xff0c;当一段文本标记有标记时&#xff0c;它会识别…

pytorch深度学习框架CUDA版本环境安装记录——牛刀杀鸡——解一个非线性方程组

目录 一、前言二、安装步骤step1. 安装显卡驱动step2. 安装cudastep3. 安装cuDNNstep4. 安装pytorch环境 三、用pytorch解个非线性方程组 一、前言 在深度学习界pytorch框架用得人越来越多&#xff0c;无论是CV机器视觉、NLP还是自然语言处理&#xff0c;目前主流的大的模型如…

Matlab-报错griddedInterpolant解决方法分享

Yiinterp1 (x,Y,xi) interp1函数的用法&#xff1a; yiinterp1 (x,Y,xi)&#xff1a;返回插值向量yi&#xff0c;每一元素对应于参量xi&#xff0c;同时由向量X与Y的内插值决定。 1.问题产生 用matlab做网格数据插值时遇到的问题 报错截图收录 2.分析原因 根据报错可知&#x…

胜叔说SI_PI_EMC

第一课 分享的目的 书籍推荐 第二课 什么是理论分析 仿真不是目的&#xff0c;仿真是验证理论分析的方法 测试不是目的&#xff0c;测试是验证理论分析的方法 第三课 信号完整性简介 小型化、高功率、高密度 传输线理论&#xff1a;传输线是由 信号路径和返回路径共同组…

【Spring Cloud】Sleuth+Zipkin全链路日志追踪接入实战

文章目录 一、背景链路追踪介绍为什么需要链路追踪?那该如何解决呢&#xff1f; 二、常见的链路追踪技术有下面这些&#xff1a;三、Sleuth3.1、Sleuth&#xff08;读作/sluːθ/&#xff09;介绍3.2、相关术语3.3、Sleuth入门 四、多线程传递traceId1.问题2.解决方案3. 业务组…

cookie和session—javaEE

1.cookie 1.1定义 单纯的说cookie指的是cookie技术&#xff0c;是客户端保存数据的一种技术 1.2保存的方式 &#xff08;1&#xff09;客户端写js代码 &#xff08;2&#xff09;服务端返回响应头set-cookie字段的值让客户端保存在本地硬盘或浏览器的相关路径中 1.3作用 …

Oracle的学习心得和知识总结(二十三)|Oracle数据库Real Application Testing之Database Replay相关视图

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

[C++]模板初阶与STL简介

目录 模板初阶与STL简介&#xff1a;&#xff1a; 1.泛型编程 2.函数模板 3.类模板 4.什么是STL 5.STL的版本 6.STL的六大组件 7.STL的缺陷 模板初阶与STL简介&#xff1a;&#xff1a; 1.泛型编程 如何实现一个通用的交换函数呢? void Swap(int& left, int& righ…

《Netty》从零开始学netty源码(四十二)之PoolChunk.runsAvailMap

runsAvailMap PoolChunk中的runsAvailMap属性用于存放可用的run的信息&#xff0c;PoolChunk中每一次分配内存都会更新runsAvailMap中可用的run的起始信息及末尾信息&#xff0c;先看下它的数据结构&#xff1a; 我们看下它的构造函数是如何赋值的&#xff1a; PoolChunk的默认…

为什么MySQL索引更适合B+树而不是二叉树、B树

概述&#xff1a; 在当今社会&#xff0c;程序员内卷非常的严重&#xff0c;如果没有过硬的技术&#xff0c;很难在众多的程序员中脱颖而出&#xff0c;例如&#xff0c;以前问数据库方面的知识&#xff0c;只会问些增删改查语句表面的东西&#xff0c;而如今却要问数据库底层…

【翻译一下官方文档】之uniapp的网络请求

uni.request(OBJECT) 发起网络请求。 参数名类型必填默认值说明平台差异说明urlString是开发者服务器接口地址dataObject/String/ArrayBuffer否请求的参数App 3.3.7 以下不支持 ArrayBuffer 类型headerObject否设置请求的 header&#xff0c;header 中不能设置 RefererApp、H5…

关于链表的题目—leetcode

第一题&#xff1a;删除链表中的指定节点 问题描述&#xff1a; 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 示例 1: 输入: head [4,5,1,9], val 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点…

【redis】缓存预热雪崩穿透击穿

【redis】缓存预热雪崩穿透击穿&#xff08;上&#xff09; 文章目录 【redis】缓存预热雪崩穿透击穿&#xff08;上&#xff09;前言一、面试题二、缓存预热三、缓存雪崩发生原因预防&#xff0b;解决高可用&#xff1a;多缓存结合&#xff1a; 人民币玩家 四、缓存穿透是什么…

谷歌云端硬盘Drive批量下载大文件或大文件夹的稳定方法

本文介绍在谷歌云端硬盘&#xff08;Drive&#xff09;中&#xff0c;快速、稳定下载大文件、文件夹的方法。 在使用谷歌Drive下载文件或文件夹时&#xff0c;我们往往会遇到下载不稳定或失败的情况&#xff1b;在下载较大的文件或文件夹时&#xff0c;这一问题出现的频率更多。…

NLP语义识别在人工智能领域中的应用与前景

自然语言处理&#xff08;NLP&#xff09;是人工智能领域中的一个重要分支&#xff0c;它致力于让计算机能够理解并处理人类自然语言。语义识别是NLP中的一个重要技术&#xff0c;它可以使计算机更好地理解人类语言的含义和意图。在本文中&#xff0c;我们将探讨NLP语义识别在人…