STL与string类的认识及简单使用

news2024/11/27 21:01:33

STL与string类的认识及简单使用

  • 一、STL
  • 二、string类
    • 构造函数
    • 容量操作
    • 访问及遍历操作
      • 迭代器
    • 修改操作
    • 非成员函数重载
      • 关系运算符重载
      • getline
  • 三、总结

一、STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
这里仅仅是简单介绍一下STL六大组件,后面结合实例细细分析
在这里插入图片描述

二、string类

【使用文档】
string从功能上来说属于STL容器,但是从发展历史上来讲,并不是。本文我们只讲述string(utf-8):编码以一个字节为准
在这里插入图片描述
string属于类模板,它的基本结构参考以下代码:

//动态增长字符数组
template <class T>
class basic_string
{
private:
	T* _str;
	size_t _size;
	size_t _capacity;
};
typedef basic_string<char> string;

构造函数

在这里插入图片描述

void test1()
{
	//无参构造,空字符串
	string s1;
	//带参构造
	string s2("我在学习string");
	//隐式构造+拷贝构造
	string s3 = "我在学习string";

	string s4(10,'#');
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;

	cout << s4 << endl;
	string s5(s3);
	string s6 = s3;
	cout << s5 << endl;
	cout << s6 << endl;

	string s7("hello world", 5);
	cout << s7 << endl;
	//s7->hello
	string s8(s7, 2, 3);
	cout << s8 << endl;
	//llo
	string s9(s7, 2, 30);
	cout << s9 << endl;
	//llo
	string s10(s7, 2);
	cout << s10 << endl;
	//llo
}

npos是-1,但是这里是无符号,实际并不是-1,是4294967295。
对于s9很明显s7(hello),长度没有30个字符;那么默认就会以str末尾之前的字符进行构造

string类对象可支持直接用cin和cout进行输入和输出,这是因为重载了流插入>>和流提取<<操作符

容量操作

函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty (重点)检测字符串释放为空串,是返回true,否则返回false
clear (重点)清空有效字符
reserve (重点)为字符串预留空间
resize (重点)将有效字符的个数该成n个,多出的空间用字符c填充
void test5()
{
	//reserve测试
	//TestPushBack();
	

	//resize  将有效字符的个数修改成n个,多出的空间用字符c填充
	string s1("www.ahao.com");
	s1.resize(3);//删除数据
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	cout << s1 << endl << endl;

	string s2("www.ahao.com");
	s2.resize(15,'n');//不扩容增加数据
	cout << s2.size() << endl;
	cout << s2.capacity() << endl;
	cout << s2 << endl << endl;

	string s3("www.ahao.com");
	s3.resize(18,'c');//扩容+插入
	cout << s3.size() << endl;
	cout << s3.capacity() << endl;
	cout << s3 << endl << endl;

}

在这里插入图片描述

size()和length()两个接口底层是完全一样的

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小

扩容问题:

void TestPushBack()
{
	string s;
	//为字符串预留500字节的空间
	s.reserve(500);
	size_t sz = s.capacity();
	cout << "capacity changed: " << sz << '\n';
	cout << s.size() << endl;
	cout << "making s grow:\n";
	for (int i = 0; i < 1000; ++i)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

不同平台下扩容规则不同,windows下vs2019是1.5倍扩容;linux下是2倍扩容
扩容也会有开销,如果我们提前知道需要多少空间,就可以使用reserve(n)开好空间

访问及遍历操作

函数名称功能说明
operator[]返回pos位置的字符,const string类对象调用
begin+ endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
范围forC++11支持更简洁的范围for的新遍历方式
void test2()//字符串遍历
{
	string s1("1234");
	// 遍历他
	cout << s1.size() << endl;
	// 1、下标 []
	for (size_t i = 0; i < s1.size(); ++i)
	{
		s1[i]++;
	}
	cout << s1 << endl;

	// 2、范围for
	for (auto& ch : s1)
	{
		ch--;
	}
	cout << s1 << endl;

	//3.迭代器 ----通用的访问形式
	//it1可以理解成一个指针,指向字符串第一个元素的位置
	string::iterator it1 = s1.begin();
	//s1.end()返回有效数据的下一个位置
	while (it1 != s1.end())
	{
		*it1 += 1;
		++it1;
	}
	it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << endl;
		++it1;
	}
}

迭代器

迭代器行为上像指针,但是却不一定是指针。
迭代器的意义在于通用,所有容器都可以使用迭代器这种方式去进行遍历和修改。
在这里插入图片描述
正向迭代器:begin+ end与反向迭代器rbegin+rend
在这里插入图片描述
rebegin()返回指向字符串最后一个字符(即其反向开头)的反向迭代器。
rend()返回一个反向迭代器,该迭代器指向字符串第一个字符(被视为其反向结尾)之前的理论元素。
反向迭代器向后迭代:增加它们会将它们移动到字符串的开头。

void test3()
{
	string s1("1234");
	//不加const
	string::iterator it1 = s1.begin();
	//auto it1=s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;
	//反向迭代器
	string::reverse_iterator rit1 = s1.rbegin();
	while (rit1 != s1.rend())
	{
		cout << *rit1 << " ";
		++rit1;
	}
	cout << endl;
}

在这里插入图片描述
const迭代器
普通的迭代器可读可写,而const迭代器可读不可写,因为const修饰this指向的内容,不能改变

// 正向  反向 -- 可以遍历读写容器数据
// const正向  const反向   -- 只能遍历,不能修改容器数据
void Print(const string& s)
{
	//遍历读,不能写
	//string::const_iterator it = s.begin();
	//const string::iterator it = s.begin();错误!这里保护的是it本身,即it不能++,但是数据可以变
	auto it=s.begin();
	while (it != s.end() )
	{
		//*it += 1;不能改变内容

		cout << *it << endl;
		++it;
	}
	cout << endl;
	//反向
	string::const_reverse_iterator rit = s.rbegin();
	//auto rit = s.rbegin();
	while (rit != s.rend())
	{
		
		cout << *rit << endl;
		++rit;
	}
}

c++11为了区别了普通迭代器和const迭代器提供了四个新的迭代器,本质和begin的const版本一样
在这里插入图片描述

修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=(最好用)在字符串后追加字符串str
c_str返回C格式字符串
find + npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回
assign为字符串分配一个新值,替换其当前内容
void test6()
{
	string s1("www.ahao.com");
	s1 += ' ';
	s1 += '!';
	s1 += "hello world";
	cout << s1 << endl;

	string s2("!!!!!!!");
	s1 += s2;
	cout << s1 << endl;
}

在这里插入图片描述

void test7()
{
	string s("www.aho.com");

	s.insert(0,"https/");//指定位置插入
	cout << s << endl;

	s.insert(6,"S");
	cout << s << endl;

	s.erase(0,6);//指定位置删除
	cout << s << endl;
	s.erase(3);
	cout << s << endl;

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

	s1.assign("www bbbb",5);  //清空原来的,赋值替换
	cout << s1 << endl;//www b

	s2.replace(6, 3, "wmh");//从6开始替换三个字符
	cout << s2 << endl;//hello wmhld hello world

	// 将' '替换成空格
	size_t pos = s3.find(' ');
	while (pos != string::npos)
	{
		s3.replace(pos, 1, "20%");
		pos = s3.find(' ', pos + 3);
	}
	cout << s3 << endl;
	
//查看文件内容:文件名不支持c++类型的字符串,只能转换成c类型的
	string file("test.cpp");
	FILE* f = fopen(file.c_str(),"r");//返回string 底层的char* 指针
	assert(f);

	char ch = fgetc(f);
	while (ch != EOF)
	{
		cout << ch;
		ch = fgetc(f);
	}
	fclose(f);


	string file;
	cin >> file;
	//取文件名后缀 test.cpp 或 test.tat.ccr.bat
	
	//size_t pos = file.find('.');//从前往后找第一个“.”的位置
	size_t pos = file.rfind('.');//从后往前找第一个“.”的位置下标

	if (pos != string::npos)
	{
		cout << pos << endl;
		string str = file.substr(pos);//返回pos及其位置之后的字符串
		cout << str << endl;
	}

}

非成员函数重载

关系运算符重载

在这里插入图片描述

void test8()
{
	string str("aaaaa");
	const char* s = "bbbbbbb";

	str == s;//bool operator== (const string & lhs, const char* rhs);
	
	s == str;//调用bool operator== (const char*   lhs, const string& rhs);
}

getline

在这里插入图片描述
当我们使用cin读取一个字符串的时候,当遇到" "或"\n"的时候会结束,但是当我们需要读取AA bbb cc这样一字符串,很显然cin已无法满足,需要借助getline,它只会读取到\n才会结束

如求最好一个单词的长度

#include <iostream>
using namespace std;
#include <string>
int main() {
    string str;
    getline(cin,str);
    size_t pos = str.rfind(' ');
    cout<<str.size()-pos-1<<endl;
}

三、总结

关于string的使用就先讲到这里吧,对于string,只使用的话借助使用文档就可以很轻松的使用。想要了解更多C++方面的知识,关注我!!!

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

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

相关文章

【计算机毕设】基于SringBoot+Vue的校园二手交易平台(含支付)

在导师的严格指导下&#xff0c;我的毕业设计终于完成了&#xff0c;毕设被推优算是给大学生活画上了圆满的句号&#xff0c;几个月的努力也没白费。在开发的过程中收获了很多&#xff0c;也遇到很多问题&#xff0c;但因怕时间来不及&#xff08;根本不知道截止时间TvT&#x…

点餐小程序实战教程04-餐品分类及餐品数据源设计

我们已经利用一定篇幅实现了店铺信息展示的功能,本篇我们来实现一下点餐的逻辑。点餐的逻辑有以下: 用户打开点餐页面,利用侧边栏导航来切换菜品初始状态用户未点餐,显示一个加号的图标点击加号显示数量,需要将菜品加入购物车,购物车显示选购菜品的数量和总价点击减号可以…

[日记]LeetCode算法·二十五——二叉树⑤ AVL树(插入+删除)附代码实现

本章的代码实现基于上一篇BST与优先队列的基类进行平衡二叉树&#xff0c;即AVL树。 文章目录 AVL的概念AVL查询效率AVL的插入1.插入节点2.更新平衡因子BF3.旋转调整树的结构3.1 LL 右旋3.2 RR 左旋3.3 LR 左右双旋3.4 RL 右左双旋 4 插入总结 AVL的删除1.寻找删除节点2.更新平…

窗口组件元素识别工具

inspect.exe 微软官方工具集成于 Windows SDK 官网下载&#xff1a;https://developer.microsoft.com/zh-cn/windows/downloads/windows-sdk/ FlaUInspect&#xff1a; 第三方开源的识别工具 https://github.com/FlaUI/FlaUInspect UIRecorder&#xff1a; WinAppDriver里…

无状态子域名爆破工具(附下载)

ksubdomain是一款基于无状态子域名爆破工具&#xff0c;支持在Windows/Linux/Mac上使用&#xff0c;它会很快的进行DNS爆破&#xff0c;在Mac和Windows上理论最大发包速度在30w/s,linux上为160w/s的速度。 总的来说&#xff0c;ksubdomain能爆破/验证域名&#xff0c;并且快和…

【P25】JMeter 取样器超时(Sample Timeout)

文章目录 一、准备工作二、测试计划设计 一、准备工作 慕慕生鲜&#xff1a; http://111.231.103.117/#/login 进入网页后&#xff0c;登录&#xff0c;页面提供了账户和密码 搜索框输入“虾” 右键检查或按F12&#xff0c;打开调试工具&#xff0c;点击搜索 二、测试计划设…

CHATGPT:北京打响大模型地方战第一枪

5月16日消息&#xff0c;最近&#xff0c;“北京市促进通用人工智能创新发展的若干措施&#xff08;2023-2025年&#xff09;&#xff08;征求意见稿&#xff09;”&#xff08;以下简称“措施”&#xff09;公布。这个措施从算力、数据、算法、应用、监管五个方向出发&#xf…

Redis学习---03

一、redis事务 (1) Redis单条命令保证原子性&#xff0c;但事务不保证原子性。 Redis 事务不是严格意义上的事务&#xff0c;只是用于帮助用户在一个步骤中执行多个命令。单个 Redis 命令的执行是原子性的&#xff0c;但 Redis 没有在事务上增加任何维持原子性的机制&#xf…

STL好难(2):string类的使用

【本节目标】 1. 标准库中的string类2. string类的模拟实现3. 扩展阅读 目录 【本节目标】 1.标准库中的string类 2. string类对象的常见构造 &#x1f349;无参构造 &#x1f349;带参构造 &#x1f349;拷贝构造 &#x1f349;用n字符 # 去初始化 &#x1f349;用字…

二进制部署高可用Kubernetes集群

SUMMARY 架构图 设备规划 序号名字功能VMNET 1备注 1备注 2备注 3 备注 4备注 50orgin界面192.168.164.10haproxykeepalived192.168.164.2001reporsitory仓库192.168.164.16yum 仓库registoryhaproxykeepalived2master01H-K8S-1192.168.164.11kube-apicontrollerscheduler…

约瑟夫问题及求解方法

文章目录 什么是约瑟夫问题&#xff1f;求解方法代码实现 什么是约瑟夫问题&#xff1f; 约瑟夫问题是一个经典的数学难题&#xff0c;其一般形式可以描述为&#xff1a; n个人&#xff08;编号从1到n&#xff09;&#xff0c;围坐在一张圆桌周围。从第一个人开始报数&#x…

chatgpt赋能Python-mac系统的python

在Mac系统上运行Python&#xff1a;一个简介 介绍 Python是一种流行的、易于学习的编程语言&#xff0c;被广泛用于各种用途&#xff0c;从数据分析到机器学习。如果您是Mac用户&#xff0c;那么您已经安装了Python&#xff0c;因为它是系统的一部分。本文将介绍如何在Mac系统…

Web基础 ( 五 ) JavaScript BOM

4.4.BOM浏览器对象模型 window代表窗体, 内置多种对象, 每种对象包含多种方法及属性 4.4.1.location 地址栏 window.location.href "url"; // 当前窗口加载指定的页面location.reload(); //刷新4.4.2.history 访问历史记录 window.history.back(); // 返回上一…

搞一搞用例图

前言 基于公司技术方案的设计比较重视用例图&#xff0c;重新学习一下相关内容。用例要说明参与者与用例之间的关系&#xff0c;那么对用例图相关要点进行梳理 用例图的定义及组成要素用例图的4种关系常用的用例图软件 定义与组成 用例图核心作用是将系统需求和参与者之间的…

DEJA_VU3D - Cesium功能集 之 110-椭圆(标绘+编辑)

前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码…

【手撕红黑树】

前言 相信很多人初学者听到了红黑树后心中不免有些心慌&#xff0c;那你看到了这篇文章后相信会有所收获&#xff0c;我其实刚开始也是对红黑树抱着一种害怕甚至是恐惧&#xff0c;但是在老师的帮助下也终于慢慢的不在恐惧了&#xff0c;你想知道为什么的话就继续往下看吧。&am…

【C,C++】内存管理new和delete

内存管理 前言正式开始几道热身题C语言动态内存管理方式C内存管理new/delete操作内置类型new和delete对于内置类型new开辟失败 operator new与operator delete函数new和delete的实现原理内置类型自定义类型 定位new表达式面试常考&#xff1a;malloc/free和new/delete的区别 前…

板子短路了?

有段时间没更新了&#xff0c;主要是最近有点忙&#xff0c;当然也因为有点“懒”。 做这行业的都知道&#xff0c;下半年都是比较忙的&#xff0c;相信大家也是&#xff01; 相信做硬件的小伙伴们&#xff0c;遇到过短路的板子已经不计其数了。 短路带来的危害&#xff1a;…

关于单目视觉 SLAM 的空间感知定位技术的讨论

尝试关于单目视觉 SLAM 的空间感知定位技术的学习&#xff0c;做以调查。SLAM算法最早在机器人领域中提出&#xff0c;视觉SLAM又可以分为单目、双目和深度相机三种传感器模式&#xff0c;在AR应用中通常使用轻便、价格低廉的单目相机设备。仅使用一个摄像头作为传感器完成同步…