C++初阶:string的使用与STL

目录

  • 1. C++标准库与STL
  • 2. string是什么
  • 3. string的使用
    • 3.1 构造与拷贝构造
    • 3.2 遍历访问方式
    • 3.3 STL中算法操作相关内容
    • 3.4 容量相关成员函数
    • 3.5 内容修改相关成员函数
    • 3.6 string类操作成员函数
    • 3.7 string的非成员函数

1. C++标准库与STL

  1. 编程语言标准库中,有着许多基础且重要的编程资源,相较于C标准库,C++在C的基础上又添加了很多实用且功能强大的功能模块,使得C++进一步在编程效率上得到了长足的进步与发展。
  2. STL(standard template libaray),即标准模板库,其为C++标准库新增内容中及其重要的组成部分之一,不仅包含了许多重要的算法内容,而且以模板的方式为我们提供了大量的可以直接使用的常用数据结构。
  3. STL有众多实现版本,各大编译器厂商都有自己实现,这里我们依照学习的STL为PJ版本(Linux操作系统下,g++编译器使用,开源)
  4. STL由六大部分(组件)组成,算法,仿函数,迭代器,容器,适配器,内存池

在这里插入图片描述

2. string是什么

  1. string为C++标准库中自带的一个类(basic_string模板的实例化),它底层实则为一个字符数组,用来存储字符串,其附带的成员函数实现了对存储其中字符串的各种操作,直接调用成员函数的方式极大的便利了我们的使用与对字符串的高效操作。
  2. string从实现与函数接口上,与STL中容器部分的设计思路相似,之所以没有划分到STL中,是因为string的出现先于STL。

3. string的使用

3.1 构造与拷贝构造

  1. 直接构造:(默认构造为空字符串,string重载了流插入操作符)
string s1;

  1. 字符串传参构造:
string s2("hello world!");

  1. 字符串指定长度构造:(从字符串头部,向后6个字符)
string s3("hello world!", 6);

  1. 使用已存在的同类型对象进行拷贝构造:
string s4(s2);

  1. 用已存在对象的一部分进行拷贝构造:(从下标为6的位置,向后6个字符)
string s5(s2, 6, 6)

  1. 使用指定个数的字符进行构造:(使用6个字符x构造一个string类)
string s6(6, 'x');

  1. 使用已存在对象的迭代器进行构造:(可指定范围,迭代器构造规则为,左闭右开)
string s7(s2.begin(), s2.end());

  1. 默认成员函数:重载的赋值运算符
    <1> 使用参数string类的内容进行赋值
    <2> 使用参数字符串进行赋值
    <3> 使用字符进行赋值
//使用赋值运算符创建string对象,会直接进行拷贝构造
string s8 = s2;

s8 = "hello world!";

s8 = 'a';

3.2 遍历访问方式

1. operator [ ]

补充:成员函数(计算string中字符串的大小,拥有多少个有效字符不计算’\0’)

  1. size()
  2. length()
for(int i = 0; i < s1.size(); i++)
{
	cout << s1[i];
}
cout << endl;

2. 迭代器(iterator)

  1. 模板与类都有自带的迭代器,在声明获得迭代器时要指定类域
  2. 成员函数 begin() 与 end() 会分别返回指向string头部与尾部的迭代器
  3. string的迭代器类型为string::iterator,名称较长,可用auto自动推演类型
  4. 迭代器支持++--,等关于加减操作遍历与调整方式,反向遍历有反向迭代器(r_begin(),r_rend())
  5. string的迭起底层实现可能为指针,其使用指针的前提为底层物理空间上有一定的连续,但并非所有的迭代器都由指针实现
  6. 迭代器可以分为四种,正向与反向迭代器,被const修饰的正向与反向迭代器
    注:const迭代器,为this指针被const修饰,string类的内容不能被改变
string s("hello world!");
//正向迭代器(正向访问)
for(string::iterator it = s.begin();it != s.end(); it++)
{
	cout << *it;
}
cout << endl;
//反向迭代器(反向访问)
for(string::reverse_iterator r_it = s.rbegin(); r_it != s.rend(); r_it++)
{
	cout << *r_it;
}
cout << endl;

//const修饰正向迭代器
for(string::const_iterator c_it = s.cbegin(); c_it != s.cend(); c_it++)
{
	cout << *c_it;
}
cout << endl;

//const修饰的反向迭代器
for(string::const_reverse_iterator cr_it = s.crbeigin(); cr_it != s.crend(); cr_it++)
{
	cout << *cr_it;
}
cout << endl;
  1. 迭代器访问方式的设计理念:
    为不同的容器,数据结构提供了统一的遍历方式,对内部实现进行了封装,提高了通用性,使得我们对STL的学习难度与成本大大降低。

3. 范围for

  1. 底层为正向迭代器访问的替换
for(auto e : s)
{
	cout << e;
}
cout << endl;

4. at

  1. 使用方式与operator[ ]类似,使用[]越界会直接报错,而使用at越界只会抛出异常
for(int i = 0; i < s.zie(); i++)
{
	cout << s.at(i);
}
cout << endl;

3.3 STL中算法操作相关内容

  1. STL中将一些我们经常会使用到的算法相关操作通过重载与模板的方式进行了实现,由此支持不同类型数据结构,容器,与几乎所有使用场景的使用,大大方便我们的使用提高了编程效率。
  2. 此类方法都在标准库的algorithm头文件中包含,且使用前需要开放命名空间std,下面我们来简单看几个。

1. reverse(逆置)

  1. 支持各种迭代器,会逆置两个迭代器之间范围内的数据,以函数模板的方式实现。
//逆置整个字符串
reverse(s.begin(), s.end());

2. swap(交换)

  1. 库中交换功能的实现方式为传引用,因此,传参时无需取地址,并且使用了函数模板的方式使得其支持各种数据类型。
//交换首尾两个位置的字符
swap(s[0], s[0] + s.size() - 1);

3.4 容量相关成员函数

  1. vs环境下,32位系统,string类的空间大小为28字节。它以动态开辟空间的方式实现对字符串的储存,初始时会给予string类16字节的大小,随着需要储存数据的增加不断为1.5倍的速度扩容当前空间。
  2. vs下对于string的每次扩容不是标准的1.5倍,同时按照一套专属的对齐机制进行空间的对齐。
  3. Linux操作系统g++编译器中,string类的扩容的机制为,初始空间大小为0,随着数据的增长从1开始不断二倍扩容,g++下的每次扩容都是标准扩容。

1.capacity

  1. 返回当前string对象的容量大小
s.capacity()

2. max_size

  1. 返回string对象理论上所能开辟的最大空间,能够承载的最大字符数
  2. 空间大小常常达不到理论上的最大字符,所以能承载的最大字符数也只是理论上的,不具有参考意义
s.max_size()

3. reserve

  1. 让string对象开辟出指定大小的空间,当指定数(Byte)大于目前空间的大小时,会进行扩容
  2. 当指定数小于目前的容量时,不会进行缩容。
//n为指定数
s.reserve(n)

4. resize

  1. 让string对象开辟出指定大小的空间,当指定数大于容量时,进行扩容,并在额外开辟出的空间中存储指定字符,当未指定字符时,默认存储字符\0
  2. 当指定数小于容量但大于有效字符数时,会进行缩容
  3. 当指定数小于有效字符数时,只会缩容到有效字符大小,不会影响数据。
//默认填充字符'\0'
s.resize(n)
//指定填充字符
s.resize(n, 'a');

3.5 内容修改相关成员函数

1. append

  1. 使用string类做参数,将参数string类的内容拼接到当前string类后
  2. 使用string类做参数,将参数stirng类的一部分内容拼接到string类后
  3. 使用字符串做参数,将参数字符串拼接到当前string类后
  4. 使用字符串做参数,将参数字符串的一部分拼接到当前string后
  5. 使用字符做参数,将指定个数的字符拼接到当前string类后
string s2("hello world!");
s.append(s2);

//将s2从下标6开始向后的六个字符拼接到s后
s.append(s2, 6, 6);

s.append("hello world!");

//将字符串的前五个字符拼接到s后
s.append("hello world!", 5);

//将3个字符a拼接到s后
s.append(3, 'a');

2. push_back

  1. 将指定的字符插入到当前string类后
//将字符a插入到string类后
s.push_back('a');

3. operator+=

  1. 将指定的参数string类的内容拼接到当前string类后
  2. 将指定的参数字符串拼接到当前string类后
  3. 将指定的参数字符拼接到string类后
string s2("hello world!");

s += s2;

s += "hello world!";

s += 'a';

4. insert

  1. 在当前string类的指定下标处,插入参数string类的内容
  2. 在当前string类的指定下标处,插入参数string类的一部分内容
  3. 在当前string类的指定下标处,插入参数字符串
  4. 在当前string类的指定下标处,插入参数字符串的一部分内容
  5. 在当前string类的指定下标处,插入指定个数的字符
string s2("hello world!");

s.insert(3, s2);

//将s2从下标为6开始向后六个字符的部分插入到s下标为3的位置上
s.insert(3, s2, 6, 6);

s.insert(3, "hello world!");

//将字符串的前五个字符插入到s下标为3的位置上
s.insert(3, "hello world", 5);

//在s下标为3的位置上插入5个'a'字符
s.insert(3, 5, 'a');

5. erase

  1. 删除从指定下标位置开始,指定长度的内容
    补充1:erase第一个函数模板的缺省参数分别为pos = 0,len = npos
    补充2:npos为string类的静态成员变量,其定义为(size_t)-1,即整形能够表示的最大数
    补充3:当指定长度大于当前string类内容的有效长度时,只会将当前string类中的内容全部删除
  2. 删除指定迭代器区间中的当前string内容
  3. 删除指定迭代器位置的当前string内容
//默认将string类清空
s.erase();
//删除string类从下标2开始往后的三个字符
s.erase(2, 3);

s.erase(s.begin(), s.end());

s.erase(s.begin());

6. assign

  1. 将参数string类的内容赋值给当前string类
  2. 将参数string类的一部分赋值给当前string类
  3. 将参数字符串赋值给当前string类
  4. 将参数字符串的一部分赋值给当前string类
  5. 将指定个数的字符赋值给当前string类
string s2("hello world!");

s.assgin(s2);

s.assgin(s2, 6, 6);

s.assgin("hello world!");

s.assgin("hello world!", 5);

s.assgin(5, 'a');

7. replace

  1. 将参数string类的内容替换到当前string类的指定区间上
  2. 将参数string类的指定部分内容替换到当前string类的指定区间上
  3. 将参数字符串的内容替换到当前string类的指定区间上
  4. 将参数字符串的指定内容替换到当前string类的指定区间上
  5. 将指定个数的指定字符串,替换到当前string类的指定区间上
string s2("hello world!");

//将s2的内容替换到以下标2开头长度为3的区间处
s.replace(2,3,s2);

//将s2的内容的指定部分替换到以下标2开头长度3的区间处
s.replace(2,3,s2,6,6);

s.replace(2,3, "hello world!");

s.replace(2,3, "hello world!", 6,6);

s.replace(2,3 , 3,  'a');

8. swap

  1. 交换参数string类与当前string类
  2. 此swap为string类中自带的成员函数swap,与算法库中的swap实现方式不同
  3. 算法库中的swap会生成中间变量,然后赋值交换,而string自带的swap会直接交换两个string指向存储空间的指针,效率更高
string s2("hello world!");

s.swap(s2);

9. pop_back

  1. 删除string类的最后一个字符
string s("hello world!");

s2.pop_back();

3.6 string类操作成员函数

1. c_str

  1. C中的字符串类型所调用的函数C++中string类不兼容,为了方便这些函数的调用,C++添加了将string类转换为C中字符串类型的成员函数
string s("test.cpp");

FILE* fp = fopen(s.c_str(), "r");

char get;

do
{
    get = fgetc(fp);
    cout << get;

} while (get != EOF);

2. data

  1. 作用与c_str相同
s.data();

3. copy

  1. 将string类中指定区间的内容拷贝给指定参数字符串
string s("hello world!");
char str[7];
s.copy(str, 6, 6);
str[6] = '\0';

4. find 与 rfind

  1. 正向与逆向寻找指定字符串
  2. 从指定下标开始寻找参数string类的内容
  3. 从指定下标开始寻找参数字符串
  4. 从指定下标开始寻找参数字符串,向后寻找指定个字符数
  5. 从指定下标开始寻找,寻找参数字符
  6. 若未找到返回npos
string s("hello world!");
string s2("hello");
//默认从下标0开始
s.find(s2);

s.find("world!");

//从下标5开始寻找参数字符串,向后寻找3个字符
s.find("wor", 5 ,3);

s.find('l');

string s3("https:///blog.csdn.net//qq_71806743?type=blog");

int pos = s3.find(":");
cout << s3.substr(0, pos) << endl;

int pos2 = s3.find('/', pos + 3);
cout << s3.substr(pos + 3, pos2 - pos - 3) << endl;

cout << s3.substr(pos2 + 1) << endl;

5. find_first_of 与 find_last_of

  1. 正向与逆向寻找指定参数字符串中字符
  2. 从指定下标开始寻找参数string类中包含的字符
  3. 从指定下标开始寻找参数字符串中包含的字符
  4. 从执行下标开始寻找参数字符
  5. 返回寻找到的下标
string s("hello world!");
string s2("ld");

//默认从0开始
s.find_first_of(s);
//默认从尾部开始
s.find_last_of(s);

s.find_first_of("ld");
s.find_last_of("ls");

s.find_first_of('l');
s.find_last_of('l');

6. find_first_not_of 与 find_last_not_of

  1. 正向与逆向寻找不是指定参数字符串中字符
  2. 从指定下标开始寻找不是参数string类中包含的字符
  3. 从指定下标开始寻找不是参数字符串中包含的字符
  4. 从执行下标开始寻找不是参数字符
  5. 返回寻找到的下标
string s("hello world!");
string s2("ld");

//默认从0开始
s.find_not_first_of(s);
s.find_not_last_of(s);

s.find_not_first_of("ld");
s.find_not_last_of("ld");

s.find_not_first_of('d');
s.find_not_last_of('d');

7. substr

  1. 返回当前string类中的指定区间的字串
string s("hello world!");

//从下标6开始,向后6个字符
string s2 = s.substr(6, 6);

8. compare

  1. 按照一定规则,长度,字符顺序比较两个字符串大小
s1.compare(s2);

3.7 string的非成员函数

1. 流插入与流提取

  1. 可以直接使用string类作为流插入流提取操作符的参数
string s1;
cin >> s1;

cout << s2 << endl;

2. operator+

  1. 因为成员函数的第一个参数只能是this指针,所以string将operator重载为了友元函数
  2. string类与string类拼接,返回string类型的临时变量
  3. string类与字符串拼接
  4. 字符与string类拼接
string s1("abc");
string s2("def");

cout << s1 + s2 << endl;

cout << s1 + "def" << endl;

cout << s1 + 'g' << endl;

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

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

相关文章

wps技巧二实现每一行文字后面统一添加数据

效果 操作 查找&#xff0c;输入^p 替换&#xff0c;输入 n m p q^p&#xff0c;测试数据&#xff0c;随意替换成你想要的 结果

MySQL-- B+ 树

一、InnoDB 是如何存储数据的&#xff1f; InnoDB 的数据是按「数据页」为单位来读写的 数据库的 I/O 操作的最小单位是页&#xff0c;InnoDB 数据页的默认大小是 16KB 单个数据页的结构及作用 多个数据页之间的逻辑连接&#xff08;双向链表&#xff09;&#xff0c;不需要物…

STM32/GD32——FreeRTOS任务管理与相关机制

芯片选型 Ciga Device — GD32F470系列 任务管理 任务处理API 操作 API 动态任务创建 xTaskCreate 任务删除 vTaskDelete 静态任务创建 vTaskCreateStatic 挂起任务 vTaskSuspend 恢复任务 vTaskResume 任务创建 BaseType_t xTaskCreate( TaskFunction_t pxTa…

vulhub中GIT-SHELL 沙盒绕过漏洞复现(CVE-2017-8386)

GIT-SHELL 沙盒绕过&#xff08;CVE-2017-8386&#xff09;导致任意文件读取、可能的任意命令执行漏洞。 测试环境 为了不和docker母机的ssh端口冲突&#xff0c;将容器的ssh端口设置成3322。本目录下我生成了一个id_rsa&#xff0c;这是ssh的私钥&#xff0c;连接的时候请指…

固态硬盘有缓存和没缓存有什么区别

固态硬盘&#xff08;SSD&#xff09;已经成为现代计算机的重要组成部分&#xff0c;它们提供了比传统机械硬盘更快的读写速度&#xff0c;从而显著提升了操作系统的运行速度和应用程序的加载效率。 其中&#xff0c;缓存&#xff08;Cache&#xff09;是固态硬盘中一个重要的…

【SpringCloud】使用Seata实现分布式事务

目录 一、Seata 框架的需求背景二、Seata 事务模式与架构2.1 Seata 组成2.2 Seata 事务模式 三、Seata 实战演示3.1 部署 Seata Server3.1.1 下载 Seata Server3.1.2 更改 Seata Server 配置3.1.3 创建 Seata Server 所需的数据库、数据库表3.1.4 启动 Seata Server 3.2 Seata …

ROS2从入门到精通1-1:详解ROS2话题通信机制与自定义消息

目录 0 专栏介绍1 话题通信模型2 话题模型实现(C)3 话题模型实现(Python)4 自定义消息 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。 &#x1f680;详情&a…

【最新版源码】快递平台独立版小程序源码|带cps推广营销流量主+前端

源码介绍&#xff1a; 快递代发快递代寄寄件小程序可以对接易达云洋一级总代 快递小程序&#xff0c;接入云洋/易达物流接口&#xff0c;支持选择快递公司&#xff0c;三通一达&#xff0c;极兔&#xff0c;德邦等&#xff0c;功能成熟 如何收益: 1.对接第三方平台成本大约4…

CoAP计算机协议,应用于物联网

什么是CoAP协议&#xff1f; CoAP&#xff08;Constrained Application Protocol&#xff0c;受限应用协议&#xff09;是一种专为物联网&#xff08;IoT&#xff09;设备和资源受限网络设计的应用层协议。它的诞生也是由于物联网设备大多都是资源限制型的&#xff0c;比如 CP…

【GPT-SOVITS-02】GPT模块解析

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…

Java之SpringBoot基础夯实——八股文【2024面试题案例代码】

1、什么是 Spring Boot&#xff1f; Spring Boot 是一个开源的Java开发框架&#xff0c;由Pivotal团队开发&#xff0c;其核心目标是简化新Spring应用的初始搭建和开发流程。它以Spring框架为基础&#xff0c;通过自动配置和约定优于配置的原则&#xff0c;极大程度地减少了手…

HarmonyOS(鸿蒙)ArkUI组件

方舟开发框架&#xff08;简称ArkUI&#xff09;为HarmonyOS应用的UI开发提供了完整的基础设施&#xff0c;包括简洁的UI语法、丰富的UI功能&#xff08;组件、布局、动画以及交互事件&#xff09;&#xff0c;以及实时界面预览工具等&#xff0c;可以支持开发者进行可视化界面…

嵌入式学习之Linux系统编程篇笔记——系统编程初探

配套视频学习链接&#xff1a;https://www.bilibili.com/video/BV1zV411e7Cy?p2&vd_sourced488bc722b90657aaa06a1e8647eddfc 目录 Linux系统编程的基本认识 什么是Linux系统编程? 什么是系统编程 系统编程的作用 怎么学习Linux系统编程? Linux系统编程基本程序框…

马斯克大模型Grok-1已开源,目前为止最大的开源大语言模型

&#x1f989; AI新闻 &#x1f680; 马斯克大模型Grok-1已开源&#xff0c;目前为止最大的开源大语言模型 摘要&#xff1a;马斯克上一周就在x上预告将开源自己的大模型&#xff0c;等了一周&#xff0c;就在刚刚&#xff0c;马斯克的大模型 Grok-1 开源了&#xff0c;Grok-…

【Canvas与艺术】砂落字现

【注意】 本作代码需要在服务器端执行&#xff0c;不可用浏览器直接打开运行。 如何安装服务器端请参考&#xff1a;https://www.cnblogs.com/heyang78/p/3339235.html 【原理】 雨粒子落下时&#xff0c;如果当前点不是黑点&#xff0c;则化身为金字的一个像素点。 【效果…

USB - USB Gadget on Linux

February, 2012. Embedded Linux Conference 2012. Agenda Introduction to USB USB Gadget API Existing Gadgets Design your own Gadget Demo Conclusio About the Author Software engineer at Adeneo Embedded Linux, Android Main activities: – BSP adaptation – Driv…

PXVDI企业级PVE免费桌面虚拟化部署教程ProxmoxVE

什么是PXVDI&#xff1f; PXVDI是一款基于Proxmox VE为底层的可商用的免费云桌面套件。对熟悉PVE的人来说&#xff0c;这点非常的点赞。首先是PVE是免费的&#xff0c;其次PVE的免费云桌面方案也极为少数。 根据官方提出的价格清单&#xff0c;免费版和商业版在功能上主要的区…

使用CURL命令确定Access-Control-Allow-Origin问题

一、问题描述 有前端小伙伴反馈ajax请求遇到跨域问题&#xff0c;也让后端小伙伴设置了跨域允许&#xff0c;但诡异的事情是在前端小伙伴的微信开发者工具中Network headers中看到了两行&#xff1a;Access-Control-Allow-Origin&#xff0c;其中居然出现了&#xff1a;“Acce…

51单片机—DS18B20温度传感器

目录 一.元件介绍及原理 二&#xff0c;应用&#xff1a;DS18B20读取温度 一.元件介绍及原理 1.元件 2.内部介绍 本次元件使用的是单总线 以下为单总线的介绍 时序结构 操作流程 本次需要使用的是SKIP ROM 跳过&#xff0c; CONVERT T温度变化&#xff0c;READ SCRATCHPAD…

Linux:系统初始化,内核优化,性能优化(2)

优化ssh协议 Linux&#xff1a;ssh配置_ssh配置文件-CSDN博客https://blog.csdn.net/w14768855/article/details/131520745?ops_request_misc%257B%2522request%255Fid%2522%253A%2522171068202516800197044705%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fb…