15.C++STL 2(string类的使用,6000字详解)

⭐本篇重点:string类的使用

⭐本篇代码:c++学习/05.string类的学习 · 橘子真甜/c++-learning-of-yzc - 码云 - 开源中国 (gitee.com)

目录

一. C/C++字符与string类

二. STL中的string类的使用

2.1 string类常见的构造与赋值

2.2 string对象的数据容量操作

2.3 string对象的遍历和访问操作(读写操作)

operator []访问和范围for

迭代器访问 

2.4 string的修改操作

a 插入删除操作 *

b 函数c_str

c 函数find和函数substr

三. string的简单应用-分离网站的协议/域名/资源

四. 下盘文章:string类的模拟实现 

一. C/C++字符与string类

        我们知道,C语言提供的字符串都是以'\0'为结尾的,在C语言中,库函数给我们提供了很多字符串函数,比如strlen(计算长度), strcmp(比较字符), strcpy(字符串拷贝), strstr(判断是否有子串), strcat(字符串追加)。这些函数可以帮助我们方便的管理字符串。

        但是在C++中,这些库函数和类分离,不符合OOP思想。并且字符串的底层需要我们自己去管理,容易越界。

        为了更方便的管理和操作字符串,C++ STL为我们提供了string类。string类为我们提供了更为丰富的接口和操作提供我们使用

二. STL中的string类的使用

        我们可以在这个文档中查找string类的信息:string文件介绍

//使用string所需头文件
#include <string>

//string包含在std命名空间中

2.1 string类常见的构造与赋值

常见构造方式如下表

构造方式解释
 string()构造空的string类对象,即空字符串
 string(const string&s)拷贝构造函数
 string(const string&s, size_t pos, size_t len = npos)

从另一个string对象 pos位置后一个字符开始拷贝,拷贝n个字符

如果没指定n,默认拷贝到结尾

 string(const char* s)用C语言字符串构造一个string对象
 string(size_t n, char c)构造一个含n个c字符的string对象
 string(const char* s, size_t n)构造一个string对象,包含s的前n个字符

测试代码如下:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1; //定义一个string空对象
	string s2("hello world!");  //应该为 "hello world"
	string s3(s2);				//应该为 "hello world"
	string s4(s2, 2);			//应该是"llo world!"

	string s5(5, 'a');			//应该是"aaaaa"
	string s6("123456", 4);		//应该是"1234"

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
	return 0;
}

运行结果如下:

 赋值方法如下

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1 = "hello world";
	string s2 = s1;
	string s3;
	s3 = s1;

	cout << s1 << endl << s2 << endl << s3 << endl;
	return 0;
}

2.2 string对象的数据容量操作

string类中给我们提供了很多函数接口

函数名称功能介绍
size()返回这个字符串的有效元素长度
length()返回这个字符串的有效字符长度(这个和size功能一样)
capacity()返回字符串空间的大小
empty()判断string对象是否为空
clear()清空一个string对象,置空。不会改变底层容量

resize(size_t n)

resiize(size_t, char c)

将有效字符变为n个,多余空间是空字符,空间不够会扩容

将有效字符变为n个,多出的空间置为字符c。空间不够会扩容

如果是减少字符,不会减少底层空间

reverse(size_t n = 0)

为字符串预留n个空间。实际上,编译器会给我们提供的空间会大于n。防止越界访问的问题。

如果n小于当前容量,不会减少容量

测试代码1

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1 = "hello world!";
	cout << "s1的有效字符" << s1.size() << endl;
	cout << "s1的长度" << s1.length() << endl;
	cout << "s1的最大容量" << s1.capacity() << endl;

	if (s1.empty())
		cout << "s1为空" << endl;
	else
		cout << "s1为不为空" << endl;

	s1.clear();//清空有效字符,清空字符不会更改其最大容量
	cout << "s1的有效字符" << s1.size() << endl;
	cout << "s1的最大容量" << s1.capacity() << endl;

	return 0;
}

运行结果如下:

 测试代码2:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1; "hello world!";
	cout << "s1的最大容量" << s1.capacity() << endl;
	s1.reserve(100);//将容量设置为100,不修改里面的内容1
	cout << "s1的最大容量" << s1.capacity() << endl;
	s1.reserve(250); // 实际设置的空间大于250
	cout << "s1的最大容量" << s1.capacity() << endl;

	string s2;
	s2.resize(100); //resize也会扩容

	string s3;
	s3.resize(100, '$');
	cout << s2 << endl;
	cout << s3 << endl;
	return 0;
}

2.3 string对象的遍历和访问操作(读写操作)

1 可以直接使用cout输出

2 可以使用类似数组的[]进行访问

3 使用迭代器访问

3 范围for 

operator []访问和范围for

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1 = "0123456789";
	//1 直接输出
	cout << s1 << endl;

	//2 使用类似数组的[]遍历访问,也能够修改
	//遍历
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;
	//修改
	for (int i = 0; i < s1.size(); i++)
	{
		s1[i] += 1;
	}


	//3.使用范围for
	for (const auto& c : s1)
	{
		cout << c << " ";
	}
	cout << endl;

	return 0;
}

运行结果如下

迭代器访问 

迭代器访问可以分为正向迭代器访问和逆向迭代器访问。

测试代码:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1 = "0123456789";

	//正向迭代器,string::iterator表示的是string类的迭代器
	string::iterator sit = s1.begin();
	while (sit != s1.end())
	{
		//解引用一个迭代器,即可找到这个位置的元素,可以访问和修改这个元素
		cout << *sit << " "; 
		sit++;
	}
	cout << endl;

	//反向迭代器,可以逆向访问和修改容器元素
	string::reverse_iterator rsit = s1.rbegin();
	while (rsit != s1.rend())
	{
		cout << *rsit << " ";
		rsit++;
	}
	cout << endl;

	return 0;
}

测试结果如下:

2.4 string的修改操作

a 插入删除操作 *

函数

说明
push_back(char c)在字符串结尾插入字符c
append在字符串结尾追加一个字符串

operator+=

operator-=

在字符串结尾追加一个字符/字符串

在字符串结尾删除一个字符/字符串

insert(size_t pos, const string& s)

erase(size_t pos, size_t len = npos)

在pos位置后面插入字符或者字符串

在pos位置删除n个字符,默认删除到结尾

operator + 

同理可以在结尾加上一个字符/字符串。但是这个没有使用引用

效率没有+=高

一般建议使用+=这个重载,简单实用且效率较高

测试代码如下

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1;
	s1 += '1';			//1
	s1 += "23";			//123
	s1.append("45");	//12345	
	s1.push_back('6');	//123456
	cout << s1 << endl;


	string s2;
	s2.insert(s2.begin(), '0'); //0
	s2.insert(0, "1234");       //12340
	cout << s2 << endl;

	s2.erase(2);				//12
	cout << s2 << endl;     
	return 0;
}

b 函数c_str

该函数用于将string类转换成为一个C式字符串

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1 = "hello world!";
	const char* s2 = s1.c_str();
	cout << s2 << endl;
	return 0;
}

c 函数find和函数substr

find用于查找字符,函数原型如下,C式字符串,string对象,单个字符都能找

找到后返回其起始下标

找不到返回npos

size_t find (char c, size_t pos = 0) const
size_t find (const char* s, size_t pos = 0) const
size_t find (const string& str, size_t pos = 0)

还有 rfind用于从pos位置开始向前查找(用法find一样)

测试代码如下:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	//find
	string s1 = "123456@qq.com";
	string s2 = "qq";
	size_t pos1 = s1.find('@');		//单个字符c
	size_t pos2 = s1.find('.');		//单个字符c
	size_t pos3 = s1.find("com");	//C字符串
	size_t pos4 = s1.find(s2);		//string对象
	size_t pos5 = s1.find("yzc");	//找不到

	cout << "pos1:" << pos1 << endl;
	cout << "pos2:" << pos2 << endl;
	cout << "pos3:" << pos3 << endl;
	cout << "pos4:" << pos4 << endl;
	cout << "pos5:" << pos5 << endl;


	return 0;
}

运行结果 

substr用于取字串

 函数原型如下:从pos开始取字串(默认0位置),如果len没有指定,默认从pos位置取到结尾处

string substr (size_t pos = 0, size_t len = npos) const;

测试代码

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s1 = "123456@qq.com";
	size_t pos1 = s1.find('@');		//单个字符c
	size_t pos2 = s1.find('.');		//单个字符c

	//substr获取pos位置后的子串
	string s2 = s1.substr(pos1);
	string s3 = s1.substr(pos2);
	cout << "s2:" << s2 << endl;	//结果应该为 @qq.com
	cout << "s3:" << s3 << endl;	//结果应该为 .com

	//可以连续获取子串,我们想要获取456
	string s4 = "123@456@789";

	size_t pos3 = s4.find('@');
	cout << s4.substr(pos3) << endl;			//获取@456@789
	int len = s4.substr(pos3 + 1).find('@');	//计算4到下一个@之间的长度
	
	string ans = s4.substr(pos3 + 1, len);
	cout << ans << endl;    //应该为456

	return 0;
}

测试结果 

三. string的简单应用-分离网站的协议/域名/资源

我们使用string分离网站的 协议,域名,资源

比如我的gitte 网站:橘子真甜 (yzc-YZC) - Gitee.com

#include <iostream>
#include <string>
using namespace std;

void Test(const string& url)
{
	cout << "网站" << url << endl;

	// 1.分离协议    找到':' 那么0到这个位置就是网站的协议
	size_t index1 = url.find(':');
	if (index1 != string::npos)
	{
		cout << "协议:" << url.substr(0, index1) << endl;;
	}

	//分离域名       找到第一个'/',':'+3 和'/'之间的就是域名
	size_t index2 = url.find('/', index1 + 3);
	if (index2 != string::npos)
	{
		cout << "域名:" << url.substr(index1 + 3, index2 - (index1 + 3)) << endl;
	}

	//分离资源    第一个'/'后面的内容就是资源
	cout << "资源:" << url.substr(index2 + 1) << endl << endl;
}

//分离网站
int main()
{
	//我们知道网站可以分为3部分,实用string类可以将这3部分分离
	//1 协议		2 域名		3资源

	string url1 = "https://gitee.com/yzc-YZC";
	//协议 https 域名 gitee.com 资源 yzc-YZC

	Test(url1);

	string url2 = "https://mp.csdn.net/mp_blog/creation/editor/143991873?spm=1001.2014.3001.4503";
	Test(url2);
	return 0;
}

运行结果如下:

四. 下篇文章:string类的模拟实现 

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

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

相关文章

神经网络(系统性学习一):入门篇——简介、发展历程、应用领域、基本概念、超参数调优、网络类型分类

相关文章&#xff1a; 神经网络中常用的激活函数 神经网络简介 神经网络&#xff08;Neural Networks&#xff09;是受生物神经系统启发而设计的数学模型&#xff0c;用于模拟人类大脑处理信息的方式。它由大量的节点&#xff08;或称为“神经元”&#xff09;组成&#xff0…

shell 基础知识2 ---条件测试

目录 一、条件测试的基本语法 二、文件测试表达式 三、字符串测试表达式 四、整数测试表达式 五、逻辑操作符 六、实验 为了能够正确处理 Shell 程序运行过程中遇到的各种情况&#xff0c; Linux Shell 提供了一组测试运算符。 通过这些运算符&#xff0c;Shell 程序能够…

数据指标与标签在数据分析中的关系与应用

导读&#xff1a;分享数据指标体系的文章很多&#xff0c;但讲数据标签的文章很少。实际上&#xff0c;标签和指标一样&#xff0c;是数据分析的左膀右臂&#xff0c;两者同样重要。实际上&#xff0c;很多人分析不深入&#xff0c;就是因为缺少对标签的应用。今天系统的讲解下…

Flutter-Web首次加载时添加动画

前言 现在web上线后首次加载会很慢&#xff0c;要5秒以上&#xff0c;并且在加载的过程中界面是白屏。因此想在白屏的时候放一个加载动画 实现步骤 1.找到web/index.html文件 2.添加以下<style>标签内容到<head>标签中 <style>.loading {display: flex;…

51单片机基础 06 串口通信与串口中断

目录 一、串口通信 二、串口协议 三、原理图 四、串口通信配置参数 1、常用的串行口工作方式1 2、数据发送 3、数据接收 4、波特率计算 5、轮询接收 6、中断接收 一、串口通信 串口通信是一种常见的数据传输方式&#xff0c;广泛用于计算机与外部设备或嵌入式系统之间…

【深度学习之回归预测篇】 深度极限学习机DELM多特征回归拟合预测(Matlab源代码)

深度极限学习机 (DELM) 作为一种新型的深度学习算法&#xff0c;凭借其独特的结构和训练方式&#xff0c;在诸多领域展现出优异的性能。本文将重点探讨DELM在多输入单输出 (MISO) 场景下的应用&#xff0c;深入分析其算法原理、性能特点以及未来发展前景。 1、 DELM算法原理及其…

动态规划子数组系列一>最长湍流子数组

1.题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int maxTurbulenceSize(int[] arr) {int n arr.length;int[] f new int[n];int[] g new int[n];for(int i 0; i < n; i)f[i] g[i] 1;int ret 1;for(int i 1; i < n-1; i,m. l.kmddsfsdafsd){int…

RabbitMQ3:Java客户端快速入门

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

【mongodb】社区版8:改变配置bindip和授权

更改配置 sudo systemctl restart mongod (base) root@k8s-master-pfsrv:/home/zhangbin# sudo tail -n 20 /var/log/mongodb/mongod.log 日志感觉是成功了:{"t":{"$date":"2024-11-19T19:57:47.076+08:00"

element dialog 2层弹窗数据同步问题

注意&#xff1a;本帖为公开技术贴&#xff0c;不得用做任何商业用途 element dialog 2层弹窗数据同步问题 如果嵌套dialog&#xff0c;也就是多层dialog嵌套 2个input&#xff0c;key用同样的值 会导致内外2层dialog&#xff0c;用相同key值的input会数据同步 原因如下&a…

C# 属性 学习理解记录

字段和属性 左边字段&#xff0c;右边属性 拓展&#xff0c;属性安全&#xff1a; 1、设置public private 和protected 等&#xff0c;只读&#xff0c;只写&#xff0c; 2、在get set 方法时&#xff0c;验证&#xff0c;异常时抛出错误

如何提取某站 MV 视频中的音乐为 MP3 音频

我们常常会遇到需要将视频中的音频提取出来并转换为 MP3 格式的情况&#xff0c;比如想要单独保存一段视频中的精彩音乐、演讲或旁白。简鹿视频格式转换器就是一款能够轻松实现这一需求的实用软件&#xff0c;它支持 Windows 和 Mac 系统&#xff0c;为不同操作系统的用户提供了…

SQLynx让数据库变得简单!

SQLynx让数据库管理和开发变得更简单&#xff0c;SQLynx是一款旨在简化飞客使用体验的创新型工具&#xff0c;它为数据库管理者、数据库分析师和开发人员提供了一个直观、易用、高效的平台&#xff0c;首先&#xff0c;SQLynx拥有直观友好的用户界面。无论您是新建还是导表&…

stm32f10x_tim.h(函数学习自用)

stm32f10x_tim.h 函数库 void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); //时基单元配置void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDe…

Centos Stream 9安装Jenkins-2.485 构建自动化项目步骤

官网&#xff1a;https://www.jenkins.io/ 1 下载 环境准备&#xff1a; 版本支持查询&#xff1a;https://pkg.jenkins.io/redhat-stable/ 安装JDK17&#xff1a;https://blog.csdn.net/qq_44870331/article/details/140784297 yum -y install epel-release wget upgradew…

ubuntu修改成静态ip

先用ifconfg查询网卡名称 例如以下的是enp10s0 enp10s0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.100.159 netmask 255.255.255.0 broadcast 192.168.100.255inet6 fe80::127c:61ff:fe4c:ab6b prefixlen 64 scopeid 0x20<link>ether…

Canvas 前端艺术家

目前各种数据来看&#xff0c;前端未来在 数据可视化 和 AI 这两个领域会比较香&#xff0c;而 Canvas 是 数据可视化 在前端方面的基础技术。所以给大家唠唠Canvas这个魔幻工具。 Canvas 介绍 Canvas 中文名叫 “画布”&#xff0c;是 HTML5 新增的一个标签。Canvas 允许开发…

WEB攻防-通用漏洞文件上传二次渲染.htaccess变异免杀

知识点&#xff1a; 1、文件上传-二次渲染 2、文件上传-简单免杀变异 3、文件上传-.htaccess妙用 4、文件上传-PHP语言特性 1、上传后门时&#xff0c;文件内容带.就不行 这时可以上传一个转换后的ip地址&#xff0c;ip地址对应网站包含后门代码 转换后的int会在访问的时候…

Linux驱动开发(9):pinctrl子系统和gpio子系统--led实验

在前面章节&#xff0c;我们有过使用寄存器去编写字符设备的经历了。这种直接在驱动代码中&#xff0c; 通过寄存器映射来对外设进行使用的编程方式&#xff0c;从驱动开发者的角度可以说是灾难。 因为每当芯片的寄存器发生了改动&#xff0c;那么底层的驱动几乎得重写。 那么…

Element-Ui组件(icon组件)

一、前言 本篇文章主要是对官网的Icon组件进行总结归纳Icon 图标 | Element Plus 在现代Web应用开发中&#xff0c;图标是用户界面设计中不可或缺的一部分。它们不仅提升了用户体验&#xff0c;还使得信息的传达更加直观和高效。本文主要对Element Plus 官方提供的Icon组件进行…