【C++】String类

目录

本文将对string常用函数进行说明

string基础介绍

string类的常用接口说明

string() &&string(const char* s)

拷贝:string (const string& str, size_t pos, size_t len = npos)

拷贝前n个进行构造:string (const char* s, size_t n);​编辑

字符串初始化:string (size_t n, char c);​编辑

string类对象的容量操作:

size() && length() && capacity()

缩小其容量以适应其当前大小:shrink_to_fit()

开辟空间:

reserve()//只会改变capacity

开空间+初始化:resize()//size和capacity动可进行改变

string类对象的修改操作

尾插:

插入一个字符push_back()

插入字符串:append()

operator+=

任意位置插入/头插

​编辑

删除:erase​编辑

替换:replace /查找:find

find_first_of//正着找

find_last_of//倒着找

交换swap​编辑

返回C格式字符串:c_str

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

begin()&&end()//迭代器

正向遍历

rbegin() && rend()//反向遍历(反向迭代器)

​编辑

operator[ ]​编辑


本文将对string常用函数进行说明

string文档:cplusplus.com/reference/string/string/?kw=string

string基础介绍

string 是一个表示文本字符串的数据类型。它是一个标准库提供的类,需要包含 <string> 头文件以及using namespace std;才能使用。

使用 string 类可以方便地处理和操作文本字符串。与使用字符数组相比,string 类提供了更多的功能和灵活性,同时也避免了手动管理内存的复杂性。

  1. 字符串是表示字符序列的类

  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性。

  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信

    息,请参阅basic_string)。

  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits

    和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。

  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个

    类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

string类的常用接口说明

string() &&string(const char* s)

 string s1;
 string s2("HelloWord");

遍历s2:

 for (size_t i = 0; i < s2.size(); i++)//s2.size():字符串的长度 
 {
     s2[i]++;
 }
 cout<<s2[i]<<" ";//遍历

     string s3="HappyEveryDay";

隐式转换:"HappyEveryDay" 是一个字符串字面值,它的类型是 const char[](或者可以隐式转换为 const char*),而 s3 的类型是 std::string。这就涉及到一个类型转换的过程,将 const char[] const char* 转换为 std::string 对象。//构造+拷贝构造->优化为->构造

拷贝:string (const string& str, size_t pos, size_t len = npos)

从pos位置拷贝到行后npos个字符

若npos超过字符串长度则拷贝到末尾截止

 string s3="HappyEveryDay";
 string s4(s3,5,3);
 string s5(s3,5,20);

npos:

npos并不是真正意义上的-1,而是无符号整型最大值,故不给值时直接打印到字符串末尾:

拷贝前n个进行构造:string (const char* s, size_t n);

字符串初始化:string (size_t n, char c);

string类对象的容量操作:

size() && length() && capacity()

 string s1("HelloWord");
 cout<<s1.size()<<endl;//9
 cout<<s1.length()<<endl;//9

二者差别不大,只是为了保持一致和使用方便就引入了size

capacity:空间大小

缩小其容量以适应其当前大小:shrink_to_fit()

 int main() 
 {
   std::string str = "Hello, world!";
   
   // 在一系列操作后,字符串对象可能有多余的容量
   std::cout << "Capacity before: " << str.capacity() << std::endl;
 ​
   // 使用 shrink_to_fit() 函数,要求字符串对象缩小容量
   str.shrink_to_fit();
 ​
   std::cout << "Capacity after: " << str.capacity() << std::endl;
 ​
   return 0;
 }

上述代码中,我们首先创建了一个 std::string 对象 str,并将其初始化为 "Hello, world!"。接下来,我们输出了字符串对象的初始容量。 然后,我们使用 shrink_to_fit() 函数,对字符串对象进行了缩小容量的请求。这个函数会使字符串对象的容量与其当前大小相匹配。 最后,我们再次输出了字符串对象的容量,以展示 shrink_to_fit() 函数的效果。

请注意,shrink_to_fit() 函数的调用并不保证一定会缩小容量。具体是否发生容量的缩小取决于实现。在某些情况下,字符串对象的容量可能会保持不变。

 

开辟空间:

reserve()//只会改变capacity

若知道要开辟多少空间,用reserve()进行开辟,提高效率,减少扩容

以如下代码为例(不同的编译器扩容方式会有差异)

 //观察扩容情况
 string s;
 size_t sz=s.capacity();
 cout<< "making s grow:\n";
 for (int i = 0; i < 100; ++i)
 {
     s.push_back('c');
     if (sz!=s.capacity())
     {
         sz=s.capacity();
         cout<<"capacity changed:"<<sz<<'\n';
     }
 }

此时的输出:

making s grow:

capacity changed:47

capacity changed:95

capacity changed:191

使用reserve():

//观察扩容情况
string s;

s.reserve(100);//提前开辟空间

size_t sz=s.capacity();
cout<< "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
    s.push_back('c');
    if (sz!=s.capacity())
    {
        sz=s.capacity();
        cout<<"capacity changed:"<<sz<<'\n';
    }
}

输出:

making s grow:

开空间+初始化:resize()//size和capacity动可进行改变

//此时初始化的值为:‘0’

s2.resize(100,'x');//全部初始化为'x'

当然resize也可以进行删除数据:

 //比size小,删除数据,保留前5个
 s2.resize(5);

虽然进行了数据删除,但是空间大小并不进行缩小(capacity不变)

string类对象的修改操作

尾插:

插入一个字符push_back()

 string s1("Hello");
 s1.push_back(' ');
 s1.push_back('!');
 cout << s1 << endl;//Hello !

插入字符串:append()

operator+=

operator+=在底层意义就是进行了封装

任意位置插入/头插

 string s1("Word");
 s1.insert(0, "Hello");
 cout << s1 << endl;
 ​
 s1.insert(5, "1");
 cout << s1 << endl;
 ​
 s1.insert(s1.begin() + 5, ' ');
 cout << s1 << endl;

输出结果:

HelloWord

Hello1Word

Hello 1Word

当然,不推荐使用,插入数据,后面数据需要后移,效率低

删除:erase

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

从pos位置删除npos个字符

 string s1("Hello Word");
 s1.erase(5,1);
 cout << s1 << endl; //HelloWord

不推荐使用,删除数据,后面数据需要前移,效率低

替换:replace /查找:find

 string s1("Hello Word i love you");
 ​
 s1.replace(pos, 1, "%20");//从pos位置后的一个字符替换为%20
 ​
 size_t pos = s1.find(' '); // 找到第一个并范围下标,若没找到返回-1
 ​
 pos = s1.find(' ',pos+3);//从pos+3位置向后找' '
 
string s1("Hello Word i love you");
 ​
 size_t num = 0;
 for (size_t i = 0; i < s1.size(); ++i)
 {
     if (s1[i] == ' ')
         ++num;
 }
 //提前开空间,减少开辟次数,提高效率,避免replace
 s1.reserve(s1.size()+2*num);
 ​
 size_t pos = s1.find(' '); // 找到第一个并范围下标,若没找到返回-1
 while (pos != string::npos)
 {
     s1.replace(pos, 1, "%20");   // 从pos位置后的一个字符替换为%20
     pos = s1.find(' ', pos + 3); // 从pos+3位置向后找' ',
 }
 cout << s1 << endl;
 //以空间换时间
 string s2("Hello Word i love you");
 string newStr;
 /*
 size_t num2 = 0;
 for (size_t i = 0; i < s1.size(); ++i)
 {
     if (s1[i] == ' ')
         ++num2;
 }
 s1.reserve(s1.size() + 2 * num2);
 */
 for (size_t i = 0; i < s2.size(); ++i)
 {
     if (s2[i] != ' ')
         newStr += s2[i];
     else
         newStr += "%20";
 }
 s2=newStr;
 cout << s2 << endl;

find 还可进行寻找文件后缀等等作用

 string file("string.cpp");
 size_t pos = file.find('.');
 ​
 if (pos != string::npos)
 {
     string suffix = file.substr(pos, file.size() - pos);//substr:提取从位置 poa 开始的前 file.size()-pos 个字符
     cout<<suffix<<endl;//.cpp
 }

find反向查找

 string file("string.cpp.txt.exe");
 size_t pos = file.rfind('.');
 ​
 if (pos != string::npos)
 {
     string suffix = file.substr(pos, file.size() - pos);//substr:提取从位置 poa 开始的前 file.size()-pos 个字符
     cout<<suffix<<endl;//.exe
 }

find_first_of//正着找

find_first_of() 函数返回一个 size_t 类型的值,表示找到的第一个匹配字符的位置。如果没有找到任何匹配的字符,则返回 std::string::npos

 #include <iostream>
 #include <string>
 ​
 int main() 
 {
   std::string str = "Hello, world!";
   std::string vowels = "aeiou";
 ​
   // 查找第一个元音字母的位置
   size_t pos = str.find_first_of(vowels);
   if (pos != std::string::npos) {
     std::cout << "The first vowel is at position " << pos << std::endl;
   } else {
     std::cout << "No vowels found." << std::endl;
   }
 ​
   return 0;
 }

在示例中,std::string 类型的字符串变量 str 存储了一个字符串,vowels 表示要查找的字符集合,即元音字母。函数 find_first_of() 被用于在 str 中查找第一个匹配元音字母的字符,并返回其位置。

find_last_of//倒着找

 #include <iostream>
 #include <string>
 ​
 int main() {
   std::string str = "Hello, world!";
   std::string vowels = "aeiou";
 ​
   // 查找最后一个元音字母的位置
   size_t pos = str.find_last_of(vowels);
   if (pos != std::string::npos) {
     std::cout << "The last vowel is at position " << pos << std::endl;
   } else {
     std::cout << "No vowels found." << std::endl;
   }
 ​
   return 0;
 }

std::string 类型的字符串变量 str 存储了一个字符串,vowels 表示要查找的字符集合,即元音字母。函数 find_last_of() 被用于在 str 中查找最后一个匹配元音字母的字符,并返回其位置。

交换swap

注意此处的swap与库中的swap不同

string::swap是将两个指针指向进行交换,而std::swap是进行深拷贝,string::swap更加高效

 // string::swap
 string s1("HelloWord");
 string s2("***********");
 cout << s1 << endl
      << s2 << endl;
 ​
 s1.swap(s2);
 cout << endl
      << s1 << endl
      << s2 << endl;
 ​
 // std::swap
 swap(s1, s2);
 cout << endl
      << s1 << endl
      << s2 << endl;
 

返回C格式字符串:c_str

 string s1("Hello Word");
 cout << (void *)s1.c_str() << endl;
 ​
 s1 += '\0';
 s1 += '\0';
 s1 += "xxxxxxx";
 ​
 cout << s1 << endl
      << s1.c_str() << endl;

c型字符串是以'\0'终止,遇到'\0'终止

而流插入/提取会忽视'\0',以s1.size();进行打印

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

begin()&&end()//迭代器

用迭代器去访问

正向遍历

 string s1("Hello Word");
 string::iterator it=s1.begin();//正向遍历
 while (it!=s1.end())
 {
     cout<<*it<<" ";
     ++it;
 }
 cout<<endl;
 //输出:H e l l o   W o r d 
 ​
 //const迭代器--只读不写
 string s3("Hello Word");
 string::const_iterator cit=s3.begin();// const_iterator
 while (cit!=s3.end())
 {
     cout<<*cit<<" ";
     ++cit;
 }
 cout<<endl;

 

另一种写法:

 for(auto ch: s1)
 {
  cout<<ch<<" ";
 }
 cout<<endl;

rbegin() && rend()//反向遍历(反向迭代器)

 //反向迭代
 string::reverse_iterator rit =s1.rbegin();//reverse_iterato:反向迭代器
 while (rit!=s1.rend())
 {
     cout<<*rit<<" ";
     ++rit;
 }
 cout<<endl; 
 ​
 //const  //const_reverse_iterator
 string::const_reverse_iterator crit =s1.rbegin();//auto crit=s.rbegin();
 while (crit!=s1.rend())
 {
     cout<<*crit<<" ";
     ++crit;
 }
 cout<<endl; 

输出:

operator[ ]

string也可以用下标的方式进行访问

 std::string str ("Test string");
 for (int i=0; i<str.length(); ++i)
 {
   std::cout << str[i];
 }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

快速幂算法详解(C++实现)

文章目录 1. 什么是快速幂2. 暴力求解代码实现缺陷分析 3. 优化一&#xff1a;取模运算的性质4. 优化二&#xff1a;快速幂算法的核心思想5. 终极优化&#xff1a;位运算优化6. 源码 这篇文章我们来一起学习一个算法——快速幂算法。 1. 什么是快速幂 顾名思义&#xff0c;快速…

将本地项目上传到gitee

本文详细介绍如何将本地项目上传到gitee 1.登录gitee创建一个与本地项目名相同的仓库 2.进入本地项目所在路径&#xff0c;打开Git Bash 3.执行初始化命令 git init4.添加远程仓库 4.1 点击复制你的HTTPS仓库路径 4.2 执行添加远程仓库命令 git remote add origin 你的…

【Vue】filter的用法

上一篇&#xff1a; vue的指令 https://blog.csdn.net/m0_67930426/article/details/134599378?spm1001.2014.3001.5502 本篇所使用指令 v-for v-on v-html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

vivado产生报告阅读分析23-时序路径特性报告

时序路径特性报告 下图显示了在“ Timing Mode ” &#xff08; 时序模式 &#xff09; 下运行“ Report Design Analysis ” &#xff08; 设计分析报告 &#xff09; 的输出示例 &#xff0c; 其中显示了设计中 10 条最差建立路径的路径特性。在 Vivado IDE 中选中“ Repo…

【教学类-06-12】20231126 (一)二位数 如何让加减乘除题目从小到大排序(以1-20之间加法为例,做正序排列用)

结果展示 优化后 优化前 背景需求&#xff1a; 生成列表 单独抽取显示题目排序方法 存在问题: 我希望 00 01 02……这样排序&#xff0c;但是实际上&#xff0c;除了第一个加数会从小到大排序&#xff0c;第二个被加数的第十位数和个位数都会从小到大排序&#xff0c;也就是…

Blender学习--模型贴图傻瓜级教程

Blender 官方文档 1. Blender快捷键&#xff1a; 快捷键说明 按住鼠标滚轮&#xff1a;移动视角Tab&#xff1a;切换编辑模式和物体模式鼠标右键&#xff1a; 编辑模式&#xff1a; 物体模式&#xff1a; 其他&#xff1a; 2. 下面做一个球体贴一张纹理的操作 2.1 效果如下…

智能优化算法应用:基于粒子群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于粒子群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于粒子群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.粒子群算法4.实验参数设定5.算法结果6.参考文献7.…

C++局域网从服务器获取已连接用户的列表(linux to linux)

目录 服务器端 代码 客户端 代码解析 服务器端 原理 遇到的阻碍以及解决办法 客户端 原理 遇到的阻碍以及解决办法 运行结果截图 总结 服务器端 代码 #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet…

安捷伦E4404B频谱分析仪,100 Hz 至 6.7 GHz

E4404B是安捷伦ESA-E系列频谱分析仪&#xff0c;它是一款能够适应未来发展需求的中高端频谱分析仪解决方案。该系列在频谱分析仪的测量速度、动态范围、精度和功率分辨能力等方面&#xff0c;都为类似价位的产品树立了性能标杆。其灵活的平台设计使得研发、制造和现场服务工程师…

这一款 Mac 系统终端工具,已经用的爱不释手了!

&#x1f525;&#x1f525;&#x1f525;作为程序员或者运维管理人员&#xff0c;我们经常需要使用终端工具来进行服务器管理及各种操作&#xff0c;比如部署项目、调试代码、查看/优化服务、管理服务器等。 相信大家用的最多的终端工具就是 Xshell、iTerm2和Mobaxterm&#…

利用ngrok实现内网穿透(全网最详细教程)

准备工具&#xff1a; 1、phpstudy 用于在本地搭建网站 2、ngrok 用于将自己的本地端口暴露到公网上&#xff0c;从而实现内网穿透 文章开始前给大家分享一个学习人工智能的网站&#xff0c;通俗易懂&#xff0c;风趣幽默 人工智能https://www.captainbed.cn/myon/ ~~~~~…

ESP32和ESP8266的ESP-MESH

ESP32和ESP8266的ESP-MESH 功能介绍一、介绍ESP-MESH二、安装painlessMesh库三、ESP-MESH基本示例&#xff08;广播消息&#xff09;四、示范 功能介绍 了解如何使用ESP-MESH网络协议通过ESP32和ESP8266 NodeMCU板构建网状网络。 ESP-MESH允许多个设备&#xff08;节点&#x…

单例模式与多线程

目录 前言 正文 1.立即加载/饿汉模式 2.延迟加载/懒汉模式 1.延迟加载/懒汉模式解析 2.延迟加载/懒汉模式的缺点 3.延迟加载/懒汉模式的解决方案 &#xff08;1&#xff09;声明 synchronized 关键字 &#xff08;2&#xff09;尝试同步代码块 &#xff08;3&am…

vue 中 js 金额数字转中文

参考&#xff1a;js工具函数之数字转为中文数字和大写金额_js封装工具类函数金额大写-CSDN博客 我使用的框架vol.core。 客户需求要将录入框的金额数字转换成中文在旁边显示&#xff0c;换了几种函数&#xff0c;最终确定如下函数 function changeToChineseMoney(Num) {//判断…

Quartz定时任务基础

springBoot有一个定时执行某个方法的 注解&#xff1a; Scheduled 可以满足挺多的需求&#xff0c;但是到了一些场景&#xff0c;就显得比较麻烦&#xff0c;比如&#xff1a; 机器待机五分钟后执行切换待机状态。如果是按照使用Scheduled注解&#xff0c;就得持久化一个表&…

【Java SE】 带你走近Java的抽象类与接口

&#x1f339;&#x1f339;&#x1f339;【JavaSE】专栏&#x1f339;&#x1f339;&#x1f339; &#x1f339;&#x1f339;&#x1f339;个人主页&#x1f339;&#x1f339;&#x1f339; &#x1f339;&#x1f339;&#x1f339;上一篇文章&#x1f339;&#x1f339;&…

2018年3月26日 Go生态洞察:Go包版本管理提案分析

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

java springboot测试类虚拟MVC环境 匹配请求头指定key与预期值是否相同

上文 java springboot测试类虚拟MVC环境 匹配返回值与预期内容是否相同 (JSON数据格式) 版 中 我们展示 json匹配内容的方式 那么 本文我们来看看Content-Type属性的匹配方式 首先 我们从返回体可以看出 Content-Type 在请求头信息 Headers 中 我们直接将测试类代码更改如下 …

C#,《小白学程序》第二十七课:大数四则运算之“运算符重载”的算法及源程序

1 文本格式 using System; using System.Text; using System.Collections; using System.Collections.Generic; /// <summary> /// 大数的四则&#xff08;加减乘除&#xff09;运算 /// 及其运算符重载&#xff08;取余数&#xff09; /// </summary> public cl…

在项目中集成marsUI

拷贝文件夹到目标项目 集成 安装相关依赖 npm i --save ant-design-vue4.x npm i less npm i nprogress npm i consola npm i echarts npm i vue-color-kit npm i icon-park/svg npm i vite-plugin-style-import 配置Vite文件 使用 效果