当前位置: 首页 > web >正文

STL之string容器

为什么要学习string类

在c语言中,字符串以"\0"结尾的一些字符的集合,并且提供了一系列的str函数,但有时候可能会越界访问,且库函数是与字符串分离的,不太符合OOP的思想,为了方便管理,c++封装了一个类

string类的常见接口

构造函数:

重点学习: 

第一个构造空的string类对象(空字符串):string s1;注意不要加()这样可能会误以为s1是函数 

第二个拷贝构造函数,可以看到这里加了&符合之前讲的避免死循环一直拷贝构造

第四个string s1("hello");  //传一个常量字符串

其余可以了解

一些简单的容量操作

 size():返回字符串的有效长度(一般用这个,length比较早期,size是与其他容器统一)

length():返回字符串的有效长度

capacity():返回空间的总大小(capacity是表示开了多大的空间,size表示有效字符长度,两则意义不一样)

这是模拟实现的string,可以看出size和capacity两则意义不同

empty():检测字符串是否为空串,是返回true,否返回false

clear():清空字符串,只是把标记位size变为0,capacity不变

reserve():为字符串预留多大的空间(一般会以1.5倍或者2倍增容,但有增容代价,如果你知道你的空间多大,可以一次性开好,例如reserve(100);如果你的参数小于原来的,则不会改变容量)

resize():将有效字符的个数改成多少个,多出的空间用字符c填充

 注意:当n<字符串长度时,这里的resize不是把多余的删除,而是把标记位size改变,下一次插入就会覆盖从而达到删除的效果

总结:resize是改变size(有效字符/标记位),reverse是改变capacity(容量)

         clear不改变底层空间的大小

operator=

string类对象的修改操作

append():在字符串后面追加字符串(可以追加字符cplusplus有详细的函数调用方法)

push_back():在字符串后面追加字符c(只能追加字符c)

pop_back():尾删一个字符c

operator+=():更推荐使用这个去代替append和push_back,尾插什么都很方便

 例如s1:hello     s2:world    s1+=s2     也就是相当于调s1.operator=(s2);

        s1:helloworld     s2:world

insert():在任意位置插入,pos表示任意一个位置,iterator是迭代器后面学

erase():在任意位置删除,pos表示任意一个位置,iterator是迭代器后面学

 

 String operations(字符串操作)

c_str():返回c格式的字符串 (在string类中是以size表示有效大小,c风格是以\0表示结束,返回c格式的字符串是在末尾加\0,而string在处理字符串是没有\0结尾表示结束,而是用size)
以下常用来分隔字符串:

find():从pos个位置开始往后找(第三个函数是表示找s中的前几个字符,例如s.find(“hello“,0,3),那就会在s这个string类对象中找hel)

rfind():从某个位置开始往前找 (注意这里的npos为-1,但类型是size_t,也就是无符号的最大,也就是任何大于或等于字符串长度的都表示以搜索整个字符串)

 

注意:find和rfind的返回值,成功找到是返回pos那个位置,失败返回npos(-1);

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

 

总结 :结合find和rfind和substr就可以分隔字符串;

string类非成员函数

少用operator+因为传值返回,导致深拷贝效率低 

重点关注relational operators(大小比较) 

 

operator>><<:可以直接输出一个string类

getline():获取一行字符串

swap():交换两个字符串类最好用这个,这个就相当于只是交换指针等内部数据结构,效率O(1)而 <algorithm> 标准库中也实现了一个通用的swap函数,这个会去调拷贝构造函数和赋值函数创建一个临时对象来完成,效率是O(n)

operator[]遍历

 

两个版本一个是const修饰的,一个是非const修饰的

用这个可以下标遍历

迭代器遍历 

这里先简单的理解迭代器为指针(后面学到更多的容器时会有更多的理解)

string::iterator it=s.begin();
while(it!=end())
{cout<<*it;++it;
}
cout<<endl;

begin():获取第一个字符的迭代器 

end():获取最后一个字符下一个位置的迭代器(这里没有进行*it操作所以[size]没有解引用就不会有危险)

rbegin()+rend():与begin和end相反,这样就可以实现反向遍历

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

注意:需要使用reverse_iterator反向迭代器 

范围for遍历

范围for本质就是迭代器遍历,只要你的类支持迭代器遍历就支持范围for,编译器会在处理时把范围for变成迭代器遍历

void test5()
{string s1("hello world");for (auto e : s1){e = e + 1;cout << e;}cout << endl;for (auto e : s1){cout << e;}cout << endl;
}

这里由于你的auto没加引用&,e不是别名,没有改s1的helloworld

简单模拟实现string类

我已经把代码上传gitee:June: 这里包含我的c++和Linux及数据结构https://gitee.com/taifanshu/day2.git

http://www.xdnf.cn/news/3452.html

相关文章:

  • Gen6D代码框架分析
  • 深度学习:基于脑机接口的虚拟世界意识控制探索
  • Qt二维码demo
  • 数据飞轮驱动AI系统持续进化
  • eNSP实验——防火墙 IPSec 配置
  • 【数据结构】 复杂度
  • MCP 多工具协作链路设计:打造真正的智能工作流
  • 单片机-89C51部分:12 pwm 呼吸灯 直流电机
  • 在 Windows 上启用 Telnet 命令
  • 【C++】extern
  • Ubuntu20.04如何优雅的安装ROS 1(胎教级教程)
  • 【软件设计师:复习】上午题核心知识点总结(三)
  • 代码随想录单调栈part1
  • 前端面试每日三题 - Day 21
  • UN R79 关于车辆转向装置形式认证的统一规定(正文部分1)
  • 文章记单词 | 第59篇(六级)
  • SpringBoot 整合 RabbitMQ:Spring AMQP
  • 突破传统!TTRL如何开启大模型无监督强化学习新篇章?
  • B站Michale_ee——ESP32_IDF SDK——FreeRTOS_2 队列
  • NU1680低成本、无固件、高集成度无线充电电源接收器
  • 速通Ollama本地部署DeepSeek-r1
  • 【Redis】String详细介绍及其应用场景
  • Angular教程前言:历史、安装与用途
  • Git---GitHub Actions
  • 大模型 Function Call
  • 力扣面试150题--旋转链表
  • 编写教育网站后端页面笔记
  • 本地部署 n8n 中文版
  • 日期有关的算法题(ctime库的使用)
  • LLM与AI Agent交互范式的演进:从工具依赖到智能协同(深度解析)