【c++】string类常见接口函数

Alt

🔥个人主页Quitecoder

🔥专栏c++笔记仓

Alt

朋友们大家好啊,本节我们来到STL内容的第一部分:string类接口函数的介绍

目录

  • 1.string类的认识
  • 2.常见接口讲解
    • 2.1 string类对象的常见构造
    • 2.2 对string对象的遍历和修改
    • 2.3 string类对象的容量操作
    • 2.4 string类对象的修改操作
      • 注意事项:

1.string类的认识

给大家分享一个c++文档库:

https://legacy.cplusplus.com/

在这里插入图片描述

字符串类是代表字符序列的对象
标准字符串类为这类对象提供了支持,其接口类似于标准字节容器的接口,但增加了专门用于操作单字节字符字符串的特性

通过下面这串代码:

typedef basic_string<char> string;

对应文档内容:

字符串类是basic_string类模板的一个实例化,它使用char(即字节)作为其字符类型,并使用默认的char_traits和分配器类型

请注意,这个类独立于使用的编码处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如lengthsize),以及其迭代器,仍将以字节(而非实际编码的字符)的方式操作

简单总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits, allocator> string;
  4. 不能操作多字节或者变长字符的序列

在使用string类时,必须包含#include头文件以及using namespace std;

2.常见接口讲解

2.1 string类对象的常见构造

构造函数

在这里插入图片描述
在这里插入图片描述

🔥string()

这个函数的功能是构建一个空字符串,也是默认构造

🔥string(const char* s)

用C-string来构造string类对象

用法如下:

string s1("hello world");

🔥string (const string&s)
拷贝构造函数,用法:

string s1("hello world");
string s2(s1);

🔥string (const string& str, size_t pos, size_t len= npos);

我们来看文档对这一部分的讲解:

在这里插入图片描述

拷贝从pos位置开始,向后len长度,如果超过剩余长度,则遍历到字符串的末尾

注意,这里有个npos缺省值,如果我的len给的nops,也会遍历到字符串末尾,简单了解一下npos

在这里插入图片描述
npos是一个无符号常量整数-1,无符号整数-1即为整形的最大值232-1

用法:

string s1("hello world");
string s2(s1);
string s3(s1, 5, 3);
string s4(s1, 5, 10);
string s5(s1, 5);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
cout << s5 << endl;

打印结果如下:

hello world
hello worldwoworldworld

注意:我们这里直接进行对对象的打印,是因为string类已经完成了对流运算符的重载

在这里插入图片描述

🔥string(const char* s, size_t n);

在这里插入图片描述
此函数的功能是拷贝字符串的前n个字符

string s("hello world", 5);
cout << s << endl;

在这里插入图片描述

🔥string (size_t n, char c);

在这里插入图片描述
这个函数的功能就是用n个字符c来构造字符串,用法:

string s(10,'x');
cout << s << endl;

打印结果:
在这里插入图片描述

2.2 对string对象的遍历和修改

现在有一个字符串,我想打印它的每个字符,或者对每个字符进行加一操作,我该如何遍历呢?

🔥operate[ ]

在这里插入图片描述

函数的功能是返回pos位置的字符

string s1("hello world");
for (int i = 0; i < s1.size(); i++)
{cout << s1[i] << " ";
}
cout << endl;

这里,字符串长度我们用s1.size()来表示,后续进行讲解

operator[]是一个重载的操作符,用于直接访问和修改字符串中特定索引位置的字符

这个地方与我们数组访问相似,但本质不同数组是对指针的解引用,而这里是对函数的调用

char& operator[] (size_t pos);

返回pos位置的引用,意味着我们除了获取pos位置的字符,还可以对这个位置进行修改

例如:

string s("abcde");
for (int i = 0; i < s.size(); i++)
{s[i]++;
}
cout << s << endl;

在这里插入图片描述
这里我们发现还有第二种重载方式:

const char& operator[] (size_t pos) const;

const定义的对象是只读的,不能对其进行修改

🔥迭代器Iterators

在这里插入图片描述

迭代器是一种允许程序员遍历容器(如数组、链表、树等数据结构)中的元素的对象,而无需了解容器的内部结构

我们来看它的使用方法再进行理解:

string s1("hello world");
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{cout << *it1 << " ";it1++;
}

迭代器是定义在string类域里面的

在这里插入图片描述

迭代器的工作原理类似于指针:它指向容器中的某个元素,并提供了访问该元素的方法。通过迭代器,可以读取它指向的元素的值,有时也可以修改这个值(取决于迭代器的类型)。迭代器可以向前或向后移动(在支持的容器中),从而遍历容器中的所有元素

在这里插入图片描述
begin作用是返回第一个有效位置的迭代器,end是返回最后一个元素的下一个位置,也就是/0的位置

在这里插入图片描述

我们再看代码,可能这串代码并不如上述的操作符重载进行对字符串的访问方便,但是迭代器的用处是非常广泛的,比如后面学到链表部分,就无法用操作符[]进行访问,所以迭代器才是最重要的方式

🔥反向迭代器rbegin()和rend()

在这里插入图片描述
它返回的是字符串末尾的迭代器,我们用这一组迭代器可以实现逆序遍历

体会一下它的用法:

string s1("hello world");string::reverse_iterator rit = s1.rbegin();while (rit != s1.rend()){cout << *rit << " ";++rit;}cout << endl;

在这里插入图片描述
除了这种版本还有const版本

const_iterator begin() const;
const string s1("hello world");
string::const_iterator it1 = s1.begin();
while (it1 != s1.end())
{cout << *it1 << " ";it1++;
}

对const字符串进行遍历,const_iterator是只读的,不可写

🔥范围for()

string s1("hello world");
for (auto e : s1)
{cout << e << " ";
}
cout << endl;

自动取容器中的数据自动进行遍历,我们可以调试一下看一下它的本质
在这里插入图片描述
在这里插入图片描述
所以范围for本质就是迭代器,我们后面模拟实现再进行讲解

2.3 string类对象的容量操作

在这里插入图片描述
🔥size

size的功能是返回字符串长度,用法如下:

string s1("hello world");
cout << s1.size() << endl;

在这里插入图片描述
🔥capacity

在这里插入图片描述
我们可以用一串代码来看一下它的扩容机制

void fun7()
{string s;size_t sz = s.capacity();cout << sz << endl;for (int i = 0; i < 100; i++){s.push_back('a');if (sz != s.capacity()){sz = s.capacity();cout << "容量:" << sz << endl;}}
}

构造一个空字符串,不断进行尾插来扩容:
在这里插入图片描述
第一次以二倍扩容,后面以1.5倍进行扩容

🔥clear

clear作用是清空有效字符,但它对capacity没有影响

string s("hello world");
size_t sz = s.capacity();
cout << s << endl;
cout << sz << endl;
s.clear();
cout << s << endl;
cout << s.capacity() << endl;

在这里插入图片描述
🔥empty

检测字符串释放为空串,是返回true,否则返回false

🔥reserve

reserve被用来预分配内存以存储一定数量的字符,从而提高字符串操作的效率。这个函数允许你指定一个期望的容量(以字符数计),std::string对象会确保它有足够的空间来存储至少这么多字符而无需进行进一步的内存分配

具体来说,当你知道将要在字符串中存储大量字符时,使用reserve可以减少因反复增加字符串大小而导致的多次内存分配和数据复制,从而提高性能

扩容可能会开辟新的空间,使用reserve我们就可以减少扩容

string s;
s.reserve(50);
cout << s.capacity() << endl;

在这里插入图片描述

reserve的调用是一个请求,而不是命令,这意味着实际的容量可能大于或等于请求的容量,具体取决于标准库的实现细节和内存分配策略

string s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
cout << s.capacity() << endl;
s.reserve(10);
cout << s.capacity() << endl;

在这里插入图片描述
reserve不会进行缩容,比当前capacity大才会进行扩容

🔥resize

在这里插入图片描述
reserve用来改变容量,resize 改变字符串的长度,并可以初始化新添加的字符(如果增加了长度)。这个函数根据传递给它的新大小参数调整字符串的长度,以下是 resize 函数的不同使用情况和它们的效果:

  1. 增加长度

    • 当新的大小大于当前字符串的长度时,resize 会增加字符串的长度,并将新增加的位置填充指定的字符,或者如果没有提供字符,则填充默认字符(即空字符 ‘\0’)
    • 示例:
      string str = "Hello";
      str.resize(10, 'x');  // 结果:Helloxxxxx
      
    • 在这个例子中,str 被扩展到长度 10,新位置被填充为 ‘x’。
  2. 减少长度

    • 如果新的大小小于当前字符串的长度,resize 会截断字符串,只留下从开头开始的新长度的字符。
    • 示例:
      string str = "Hello, World!";
      str.resize(5);  // 结果:Hello
      
    • 这里 str 被缩短到前 5 个字符,即 “Hello”
  3. 不改变长度

    • 如果新的大小等于当前字符串的长度,resize 实际上不会对字符串做任何修改。
    • 示例:
      string str = "Hello";
      str.resize(5);  // 结果:Hello
      
    • 在这个例子中,str 保持不变

使用注意:

  • resize 直接修改字符串对象本身,不返回新的字符串
  • 如果你增加字符串长度并且不指定填充字符,则填充空字符‘/0’
  • 减少字符串长度时,被移除的字符将被丢弃,并且无法恢复
  • 使用 resize 能有效地控制字符串的长度,对于控制内存使用和避免越界访问特别有帮助

2.4 string类对象的修改操作

🔥push_back

在字符串后尾插字符c

string s("abcd");
s.push_back('e');
cout << s << endl;

打印结果:

abcde

🔥append

在字符串后追加一个字符串

string s("abcd");
s.push_back('e');
cout << s << endl;
s.append(" higkl");
cout << s << endl;

在这里插入图片描述
在这里插入图片描述
append也可以插入string,或者插入string的部分。还可以插入n个字符

string s1("hello ");
string s2("world");
s1.append(s2);
cout << s1 << endl;

在这里插入图片描述
也可以插入字符串的迭代器区间

string s1("hello ");
string s2(" world ");
s1.append(s2);
cout << s1 << endl;

比如上述代码,我不需要world前面和后面的空格,我可以这样追加:

string s1("hello ");
string s2(" world ");
s1.append(++s2.begin(),--s2.end());
cout << s1 << endl;

在这里插入图片描述
🔥operate+=

在这里插入图片描述

operate+=使用起来就非常方便了,我们可以直接追加一个string对象,或者一个字符串,或者一个字符

🔥insert和erase

在这里插入图片描述
insert功能也非常多,主要就是在指定位置插入字符串,我们来看几个示例:

string s1("abcde");
s1.insert(0, "xxx");
cout << s1 << endl;

在头部插入
在这里插入图片描述
其他功能也十分类似,我们通过文档也可以自己写出来

在这里插入图片描述

string& erase (size_t pos = 0, size_t len = npos);

从pos位置开始删除,这里pos给的缺省值,如果不传参,则全部删除,len的缺省值为npos,我们前面已经提到过,如果len大于剩余字符长度,也会全部删除掉

🔥replace

在这里插入图片描述
对string对象内容进行替换,也有多种功能,我们简单举例:

string s1("abc def ghi");
s1.replace(3, 1, "xx");
cout << s1 << endl;

索引3开始的1个字符替换为字符串"xx"

abcxxdef ghi

🔥find
在这里插入图片描述
find用于搜索字符串中第一次出现的指定子字符串或字符的位置。如果找到了指定的子字符串或字符,find会返回它开始的位置的索引;如果没有找到,它会返回一个特殊的常量std::string::npos,表示未找到任何匹配。

find函数有几个重载版本,允许你在字符串中搜索不同类型的数据,包括单个字符、字符串和字符数组,还可以指定从哪个位置开始搜索

find函数的常见用法如下:

  1. 搜索字符

    string str = "Hello, World!";
    size_t pos = str.find('W');
    if (pos != string::npos) {cout << pos << endl;// 找到了字符 'W'
    }
    
  2. 搜索子字符串

    string str = "Hello, World!";
    size_t pos = str.find("World");
    if (pos != string::npos) {// 找到了子字符串 "World"
    }
    
  3. 从指定位置开始搜索

    string str = "Hello, World! World!";
    size_t pos = str.find("World", 8); // 从索引8开始搜索
    if (pos != string::npos) {// 找到了第二个 "World"
    }
    

注意事项:

  • find返回的位置索引是基于0的,即字符串中第一个字符的位置索引为0。
  • 如果find没有找到匹配项,它将返回string::nposstring::npossize_t类型的最大值,用于表示无效的位置
  • 使用find可以非常方便地检查一个字符串是否包含另一个字符串或字符,以及确定它们的位置

find函数提供了一种简单而有效的方法来搜索字符串中的内容,是处理字符串时常用的功能之一

本节内容到此结束!感谢大家阅读!!

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

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

相关文章

Jackson解析Json数据

1.概述 Jackson 和 FastJson 一样&#xff0c;是一个 Java 语言编写的&#xff0c;可以进行 JSON 处理的开源工具库&#xff0c;Jackson 的使用非常广泛&#xff0c;Spring 框架默认使用 Jackson 进行 JSON 处理。 Jackson 有三个核包&#xff0c;分别是 Streaming、Databid、…

【实战JVM】类的生命周期

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

百度OCR身份证识别C++离线SDKV3.0 C#对接

百度OCR身份证识别C离线SDKV3.0 C#对接 目录 说明 效果 问题 项目 代码 下载 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 SDK 简介 本 SDK 适应于于 Windows 平台下的⾝份证识别系统,⽀持 C接⼜开发的 SDK,开发者可在VS2015 下⾯进⾏开发&#xff08;推荐…

推荐学习什么编程语言?

选择编程语言学习时&#xff0c;除了就业因素外&#xff0c;还可以考虑以下几个方面来决定学习哪些编程语言&#xff1a; 个人兴趣与目标&#xff1a;如果你对某个特定领域感兴趣&#xff0c;比如游戏开发、数据分析、人工智能等&#xff0c;可以选择与该领域紧密相关的编程语言…

Altair® Access™ 面向研究人员和工程师的 HPC 作业提交门户

Altair Access™ 面向研究人员和工程师的 HPC 作业提交门户 Access 具有一个简单、强大且统一的界面&#xff0c;可以从中提交和监控远程集群、云或其他资源的相关作业&#xff0c;使工程师和研究人员能够专注于主要活动&#xff0c;减少在应用程序运行及数据移动上投入的时间。…

搭建第一个Web服务器(在eclipse或idea上部署Tomcat服务器)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

2024年ERP软件上中下游结构分析及细分行业研究

环洋咨询Global Info Research的ERP软件市场调研报告提供ERP软件市场的基本概况&#xff0c;包括定义&#xff0c;分类&#xff0c;应用和产业链结构&#xff0c;同时还讨论发展政策和计划以及制造流程和成本结构&#xff0c;分析ERP软件市场的发展现状与未来市场趋势&#xff…

nandgame中的条件判断EQ(== 相等)、GT、LT、NOT、GOTO、IF_GOTO

相等从堆栈中弹出两个顶部值并进行比较。 如果它们相等&#xff0c;则推送值-1&#xff08;十六进制中的FFFF&#xff09;。 否则推送0。在条件语句中&#xff0c;FFFF代表真&#xff0c;0代表假。示例 之前 之后 堆栈 堆栈 7 0 8 结果如下&#xff1a; 代码 POP_D POP_A…

AI大模型探索之路-应用篇8:Langchain框架LangServe模块-专注于AI模型的部署

目录 前言 一、概述 二、功能特性 三、REST API 开发 四、Postman调用测试 五、Client调用测试 总结 前言 随着AI大语言模型&#xff08;LLM&#xff09;的技术的不断演进&#xff0c;AI应用的开发和部署变得越来越复杂。在这样的背景下&#xff0c;LangServe应运而生—…

设计模式——2_7 状态(State)

欲买桂花同载酒&#xff0c;终不似&#xff0c;少年游 ——刘过《唐多令芦叶满汀州》 文章目录 定义图纸一个例子&#xff1a;如何模拟一个转笔刀自动转笔刀PencilPencilSharpener 投诉和改善钝刀BladePencilSharpener 没有铅笔PencilSharpener if if ifStatePencilSharpener 碎…

48-基于腾讯云EKS的容器化部署实战

准备工作 在部署IAM应用之前&#xff0c;我们需要做以下准备工作&#xff1a; 开通腾讯云容器服务镜像仓库。安装并配置Docker。准备一个Kubernetes集群。 开通腾讯云容器服务镜像仓库 在Kubernetes集群中部署IAM应用&#xff0c;需要从镜像仓库下载指定的IAM镜像&#xff…

亚马逊、速卖通、lazada测评自养号与机刷有何区别?

在亚马逊平台&#xff0c;买家评价的重要性无需多言。许多消费者在决定购买产品前&#xff0c;都会习惯性地查看相关评论&#xff0c;对比同类产品的买家反馈&#xff0c;从而做出更明智的选择。正因如此&#xff0c;测评成为各大电商平台不可或缺的一种推广策略&#xff0c;亚…

C++ 模拟实现 STL 中的 set、map 与 multiset、multimap

目录 一&#xff0c;RB_tree 的实现 1&#xff0c;RB_tree 的节点与数据结构 2&#xff0c;RB_tree 的迭代器 3&#xff0c;RB_tree 的构造 4&#xff0c;RB_tree 的元素操作 5&#xff0c;完整代码 二&#xff0c;set 与 multiset 的实现 1&#xff0c;set 2&#x…

从零开始:Elasticsearch简介与详解

大家好,我是小米,今天我来和大家聊一聊阿里巴巴面试题中常见的一个话题:Elasticsearch。作为一名喜欢分享技术的小伙伴,我深知在技术的道路上,多一份了解就多一份优势。那么,让我们一起来探索一下Elasticsearch的特点、功能、场景以及与竞品的对比分析吧! 特点 特点是…

js爬虫puppeteer库 解决网页动态渲染无法爬取

我们爬取这个网址上面的股票实时部分宇通客车(600066)_股票价格_行情_走势图—东方财富网 我们用正常的方法爬取会发现爬取不下来&#xff0c;是因为这个网页这里是实时渲染的&#xff0c;我们直接通过网址接口访问这里还没有渲染出来 于是我们可以通过下面的代码来进行爬取: …

1. VirtualBox安装CentOS

安装 VirtualBox 地址:https://www.virtualbox.org/wiki/Downloads 版本: 6.1和7.0+版本都可以 安装: windows上安装需要admin权限,右键菜单选中 “Run as administrator” 安装 CentOS 6.10 地址:https://vault.centos.org/6.10/isos/x86_64/ 版本: 如果不需要GUI,选择…

混合云构建-如何通过Site to Site VPN 连接 AWS 和GCP云并建立一个高可用的VPN通信

如果我们的业务环境既有AWS云又有GCP云,那么就需要将他们打通,最经济便捷的方式就是通过Site-to-Site VPN连接AWS和GCP云,你需要在两个云平台上分别配置VPN网关,并建立一个VPN隧道来安全地连接这两个环境,我们下面演示一个高可用场景下的S2S VPN线路构建,采用动态BGP协议…

利用dbschema工具导出数据库结构

dbschema是SinoDB数据库的一个命令行工具&#xff0c;可以用来导出SinoDB数据库的所有对象&#xff08;如表、触发器、视图等&#xff09;的元数据。以下是常见的使用方法&#xff1a; 1、导出数据库中所有的表结构到文件db.sql $dbschema -d your_database_name -t all db.sq…

岛屿个数c++

参考文章 岛屿个数1岛屿个数2 题目 输入样例&#xff1a; 2 5 5 01111 11001 10101 10001 11111 5 6 111111 100001 010101 100001 111111输出样例&#xff1a; 1 3样例解释 对于第一组数据&#xff0c;包含两个岛屿&#xff0c;下面用不同的数字进行了区分&#xff1a; 0…

Torch not compiled with CUDA enabled问题解决过程记录

1. 背景 运行大模型的时候&#xff0c;出现错误:Torch not compiled with CUDA enabled 原因&#xff1a;并不是电脑安装了nvdia显卡驱动就可以的&#xff0c;还需要安装 NVDIA GPU Computing Toolkit&#xff08;即CUDA Toolkit&#xff09;cudnn 另外还需要确保安装的pyt…