【C++】string类接口的了解和使用

news2025/7/20 6:14:18

为什么我们要学string类呢?那是必须是为了方便啊!在C语言中,我们创建一个字符串,有很多操作或者必须要注意的细节会把控不住,所以C++中出现了string类,让我们应对字符串等oj题也方便快捷了许多!


目录

一、STL的介绍

二、标准库中的string类

1、简介string​编辑

2、库中的string类的常用接口说明​编辑

 1.构造函数

           2.npos 

           3.遍历 

3.capacity

 1.size,lenth,max_size,capacity

 2.shrink_to_fit

 3.reserve、resize(重点)

4.operator[],at

5、Modifiers

1.push_back, append, operator+=

         2.insert,erase

         3.assign,replace(不重要)

         4.find,c_str,substr

总结 


一、STL的介绍

STL(standard template libaray- 标准模板库 ) C++ 标准库的重要组成部分 ,不仅是一个可复用的组件库,而且 是一个包罗数据结构与算法的软件框架
STL 的六大组件 :仿函数、算法、迭代器、空间配置器、容器、配接器。
这些在我们接下来的学习都会深入学习!
网上有句话说: 不懂 STL ,不要说你会 C++” STL C++ 中的优秀作品,有了它的陪伴,许多底层的数据结构
以及算法都不需要自己重新造轮子,站在前人的肩膀上,健步如飞的快速开发。

二、标准库中的string类

1、简介string

 string是一个模板,是因为编码不同,导致char的字节数不同,所以需要模板来适应不同的编码类型,原型差不多就是这样的:

 我们接下来研究的:utf-8,char为一个字节的string类

 

 2、库中的string类的常用接口说明

   1.构造函数

在学习任何类之前,当然要先看它的构造函数了!(我们只了解重要且常用的)

 构造函数:直接上例子:

  可以看得出,s1为默认的构造函数

s2是带参的构造函数(理解:会开辟一段空间,将内容存起来)

s3的构造方式,会发生隐式类型转换,会产生临时变量,先构造,再拷贝构造,优化后就是构造

s4构造是用n个char c 字符去初始化

拷贝构造:自定义类型拷贝会发生深拷贝,所以形参一般要用引用减少拷贝,提高效率

s5,s6都是拷贝构造


2.npos

npos是一个静态成员变量,无符号整型,是一个极大的数。

对于这个构造函数,是在str的pos位置开始向后len的长度,这段字符串进行初始化。

那默认不传len,len的值就是npos,是一个非常大的数,当len大于str的长度时,默认到了str的最后一位。

3.遍历 

共有三种遍历方式:

void test2()
{
	string s1("12345678");
	// 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、迭代器  -- 通用的访问形式
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 1;
		++it1;    // 把string里的内容每一个都加了一
	}

	it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << " ";   //打印每一个内容
		++it1;
	}
	cout << endl;
}

可以看的出:operator[]有两个接口,一个是有const,一个没有const

operator[],是一个可读且可写的接口。

当const只读对象调用时,就会调用const接口

当只写对象调用时,就会调用非const,

所以对于即可写又可读的接口函数来说,就有两个版本,const和非const

  

还有一点:operator[]内部有防止越界访问的功能:assert(pos<=size);

迭代器的遍历方法:

这里的迭代器是string类的自定义的一种类型,需要string::

迭代器我们现在可以看作是 和指针相差不多的东西(行为像指针),但他又不是指针,具体的底层我们后面会见面。

begin()就是指向第一个位置,end()指向最后一个有效字符的下一个位置

迭代器要注意的地方:

我们可以看到:迭代器也分为const和非const,那什么时候分别用哪个呢?

const_iterator:只能在const对象下使用,并且const迭代器可以改变迭代器本身,但不能改变迭代器所指向的内容 

迭代器有正向迭代器和反向迭代器:

void Print(const string& s)
{

	// 只读不写,可以遍历改变it,但不能改变他指向内容
	string::const_iterator it = s.begin(); //正向迭代器
	while (it != s.end())
	{
		// *it += 1;  错误!

		cout << *it << " ";
		++it;
      //正向迭代器就是正着迭代++
	}
	}
	cout << endl;

	//string::const_reverse_iterator rit = s.rbegin();
	auto rit = s.rbegin();       //反向迭代器
	while (rit != s.rend())
	{
		cout << *rit << " ";
		++rit;
       //都是++,这里不可以类比指针反向迭代器就是反着迭代++
	}
	cout << endl;
}

学会了吗?


 3.capacity

1.size,lenth,max_size,capacity

在string中,我们会怎么描述字符串长度??length是不是更贴合,那为什么又有size呢??

因为string是早于stl的,在它之后size更普遍适用,为了普遍化,那只能添加一个size了

size==length,就是求长度或者字符个数。(length淘汰!!)

只读接口,加const

 capacity:string的容量,和size可不相同。

clear:因为stl只是规范了每个接口名字或者参数,但并没有将每一个容器函数的细节拿捏死,所以对于clear,我们并不知道他清空数据以后,是否还要回收空间。得需要验证!

void test4()
{
	string s("hello world");
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.capacity() << endl;

	s.clear();
	cout << s << endl;
	cout << s.capacity() << endl;
}

可以发现,clear之后并没有回收空间,也不会缩容

empty(),就是来判空的


2.shrink_to_fit

当capacity大于size时,将size和capacity保持一致,会缩容,但缩容代价还是挺大的,一般也不这么搞。


3.reserve、resize(重点)

  只改变capacity

在我们知道需要多少空间时,插入数据,为了防止反复扩容(扩容代价大),我们可以提前预留空间,开辟好。

那到底是怎么扩的呢??一次扩多少?

我们在vs和g++上分别测试得出:vs上面会1.5倍扩容,但是存在内存对齐问题,会有些许偏差,但空间还是大于我们要开辟的。g++就是2倍扩容,要多少扩多少,不会有偏差。

 第一次预留500,第一次扩容到766,第二次扩容1149,差不多就是1.5倍

resize:它改变的是 size

当n不同,resize会分为三种情况:(n为size改变后的值)

举例说明:

void test6()
{
    //当n<size,不会缩容(删数据)

	string s1("hello world");
	s1.resize(4);
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	cout << s1 << endl << endl;

    //当size<n<=capacity (插入数据)

	string s2("hello world");
	s2.resize(15, '#');
	cout << s2.size() << endl;
	cout << s2.capacity() << endl;
	cout << s2 << endl << endl;

    //当n>capacity,  (扩容+插入数据)

	string s3("hello world");
	s3.resize(20, '#');
	cout << s3.size() << endl;
	cout << s3.capacity() << endl;
	cout << s3 << endl << endl;
}

所以resize功能还是比较完善健全的。

 4.operator[],at

 他们是一样的,都是读写到string中的某个值,进行操作。

但是区别在于:当发生越界时,operator[]会直接assert()报警告;而at则会抛异常(后面我们会详细了解)

5、Modifiers

1.push_back, append, operator+=

插入:

push_back :尾插

下面通过举例来观察: 

void test7()
{
 //push_back
	string s1("hello world");
	s1.push_back('x');
	s1.push_back('y');
	cout << s1 << endl;

 //append
	string s2("1111111111");
	s2.append(s1);
	cout << s2 << endl;

//operator+=
	string s3("666");
	s3 += ' ';
	s3 += "hello world";
	s3 += s2;
	cout << s3 << endl;
}

 

2.insert,erase

适用于头插,头删,中间插入和删除

但这两种函数我们都不建议经常使用,因为它的效率很低,在删除或者插入时,就会有数据挪动,效率很低。

void test8()
{
	string s("hello world");
	s.insert(0, "bit");
	cout << s << endl;

	s.erase(0, 3);
	cout << s << endl;

	s.insert(5, "bit");
	cout << s << endl;

	s.erase(5,3);
	cout << s << endl;

	s.erase(5);  //第二个参数不提供,默认是npos,直接从pos删到最后一个。
	cout << s << endl;
}

 3.assign,replace(不重要)

assign(功能):先clear,再赋值 

replace:替换内容

void test9()
{
	string s("3456789");
	s.assign("1234");
	cout << s << endl;

	string s1("hello world");
	s1.replace(6, 10, "666");
	cout << s1;
}

4.find,c_str,substr

find:也有缺省值,默认不提供,直接找到最后一个

c_str:取出C形式字符串(底层指针)

  

substr:取出str的一部分,再将其构建成新对象返回

  

getline:输入可以中间带空格的字符串


总结

这就是我们经常要用到的函数接口,更底层的内容,需要我们在模拟实现的时候,去好好感悟,下期再见!

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

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

相关文章

linux搭建redis数据库实现远程c语言访问

文章目录 linux安装reidis数据库c语言使用hiredis库实现redis数据库的操作测试代码使用hiredis库制作一个redis数据库管理系统linux安装reidis数据库 linux安装reidis数据库 sudo apt-get install redis-server使用systemctl命令查看redis服务运行状态 sudo systemctl statu…

Visual C++ 2010开发的程序在其它电脑上运行提示“找不到MSVCR100D.dll”原因及解决

Visual C 2010开发的程序在其它电脑上运行提示“找不到MSVCR100D.dll”原因及解决 Microsoft Visual C&#xff08;简称Visual C、MSVC、VS或VC&#xff09;2010是微软公司的免费C开发工具&#xff0c;具有集成开发环境&#xff0c;可提供编辑C语言&#xff0c;C以及C/CLI等编程…

惊喜:2023前瞻版Java面试指南,不止八股文

前言&#xff1a; 2022年马上就要过去了&#xff0c;即将要到来的就是2023年的金三银四面试季&#xff0c;随着政策的放宽&#xff0c;经济的逐步复苏&#xff0c;岗位的需求也会越来越大&#xff0c;所以趁这段时间进行知识储备将会是最好的时间段&#xff0c;永远要做快人一…

卷积神经网络——李宏毅机器学习笔记

以Image Classification为例 第一个解释角度&#xff1a; 先将不同尺寸的image&#xff0c;rescale成大小一样的尺寸&#xff0c;再丢到model中。 下图中&#xff0c;我们希望Cross entropy 越小越好 在计算机视角下的图片&#xff1a; 3 channels 对应R G B三个通道 随着模…

VirtualBox安装openEuler方案一

下载&#xff1a; https://www.openeuler.org/zh/mirror/list/ 根据设备架构选择对应的版本&#xff1a;windows是x86架构 选择下面这个4.2G大小的&#xff1a; 安装&#xff1a; 安装部分建议参考另一篇文章&#xff1a;virtualbox安装openEuler-方案二 下面部分的安装…

Flink CDC 2.3 发布,持续优化性能,更多连接器支持增量快照,新增 Db2 支持

01Flink CDC 简介Flink CDC [1] 是基于数据库的日志 CDC 技术&#xff0c;实现了全增量一体化读取的数据集成框架。配合 Flink 优秀的管道能力和丰富的上下游生态&#xff0c;Flink CDC 可以高效实现海量数据的实时集成。作为新一代的实时数据集成框架&#xff0c;Flink CDC 具…

电子班牌解决方案-最新全套文件

电子班牌解决方案-最新全套文件一、建设背景二、建设思路三、建设方案四、获取 - 电子班牌全套最新解决方案合集一、建设背景 信息技术已渗透到经济发展和社会生活的各个方面&#xff0c;人们普遍关注教育信息化在提高国民素质和增强国家创新能力方面的重要作用。 《国家中长…

分块查找 确定查找位置

此时 当low和high指在某个相同的位置mid时&#xff08;此时low,mid,high指向同一位置&#xff09;&#xff0c;mid的左边元素小于19&#xff0c;因为low左边的元素一定小于19&#xff0c;mid右边的元素大于19&#xff0c;因为high右边的元素大于19。我们需要寻找的是位置是大于…

PMI新人才三角如何构建自己的影响力?【洞见1】

背景&#xff1a; VUCA时代&#xff0c;Volatility&#xff08;易变性&#xff09;&#xff0c;Uncertainty&#xff08;不确定性&#xff09;&#xff0c;Complexity&#xff08;复杂性&#xff09;&#xff0c;Ambiguity&#xff08;模糊性&#xff09;&#xff0c;这个时代…

c++new和delete的匹配问题与raii的定制删除器

目录 1.关于new与delete 2.智能指针的定制删除器 1.关于new与delete 这里我想介绍的是new[]与delete[]没有配套使用带来的影响。这个是否发生错误和使用的ide有很大的关系。&#xff08;这里我用vs平台做示例&#xff09; 如果对内置类型采用new[]来开辟开辟空间&#xff0c…

postgresql源码学习(50)—— 小白学习Dtrace追踪源码函数调用

不知不觉第50篇了&#xff0c;昨天在文章里&#xff08;https://mp.weixin.qq.com/s/AzBGzYhGxYjSf7Sptj55lQ&#xff09;学到一个追踪源码执行情况的利器 —— Dtrace&#xff0c;本篇记录下实验和笔记。 一、 解决痛点 学习以来一直有一个疑惑&#xff0c;如何将pg中执行的SQ…

Spring Boot 3.0 正式发布,这份升级指南必须收藏

Spring Boot 3.0 现已正式发布&#xff0c;它包含了 12 个月以来 151 个开发者的 5700 多次代码提交。这是自 4.5 年前发布 2.0 以来&#xff0c;Spring Boot 的第一次重大修订。它也是第一个支持 Spring Framework 6.0 和 GraalVM 的 Spring Boot GA 版本&#xff0c;同时也是…

Nginx环境搭建及前端部署教程(Windows版)

1、Nginx简介 Nginx (engine x) 是一个轻量级、高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。几乎可以做到 7 * 24 小时不间断运行&#xff0c;即使运行几个月也不需要重新启动&#xff0c;还能在不间断服务的情况下对软件版本进行热更新。性…

2022年,数字化转型升级,越来越重要

所谓数字化营销&#xff0c;指的是使用数字传播渠道推广产品和服务&#xff0c;从而以一种及时、相关、定制化和节省成本的方式与消费者进行沟通。 进入2022年&#xff0c;数字化转型升级&#xff0c;变得越来越重要。 01政策推动数字化发展 国家“十四五”期间将加快推进企业…

arthas进阶版排查问题之idea插件工具操作

arthas前面的文章讲了怎么去使用命令排查线上问题&#xff0c;线上出了问题就需要我们去排查问题和处理程序异常&#xff0c;但是线上一般出问题不太好解决&#xff0c;总有一些奇怪的问题&#xff0c;当然很多场景是测试测试不到的&#xff0c;我们不能百分百保证线上不出问题…

Unreal地形高级材质之根据斜率分配材质

目的&#xff1a;根据地形的斜率来混合地形材质&#xff0c;制作地形时&#xff0c;当地形有高度抬升时&#xff0c;被拉伸部位的贴图会出现拉伸&#xff0c;或者想要在拉伸区域使用其他类型种类的贴图时。如果使用笔刷对地形进行更改是耗费时间的&#xff0c;所以想要整体一次…

数据结构中的树和二叉树(0基础讲解+代码)

树和二叉树树的定义树的一些基本概念树的代码链接方式二叉树完全二叉树和满二叉树二叉树的性质链式二叉树前序遍历后序遍历中序遍历层序遍历二叉树的深度二叉树第k层的结点个数二叉树的叶子节点个数总结前言&#xff1a;前面我们所学习的数据结构比如链表&#xff0c;顺序表&am…

【博客542】k8s使用EndpointSlices扩展大规模service后端服务数量

k8s使用EndpointSlices扩展大规模service后端服务数量 EndpointSlices 端点切片&#xff08;EndpointSlices&#xff09; 提供了一种简单的方法来跟踪 Kubernetes 集群中的网络端点&#xff08;network endpoints&#xff09;。 它们为 Endpoints 提供了一种可扩缩和可拓展的替…

长时间序列模型DLinear(代码解析)

前言 今年时间序列SOTA&#xff0c;DLinear模型&#xff0c;论文下载链接&#xff0c;也可以看我写的论文解析当然最好是读原文。Dlinear&#xff0c;NLinear模型Github项目地址&#xff0c;下载项目文件这里提供我写过注释的项目文件&#xff0c;下载地址 参数设定模块(run_…

图神经网络之预训练大模型结合:ERNIESage在链接预测任务应用

1.ERNIESage运行实例介绍(1.8x版本) 本项目原链接&#xff1a;https://aistudio.baidu.com/aistudio/projectdetail/5097085?contributionType1 本项目主要是为了直接提供一个可以运行ERNIESage模型的环境&#xff0c; https://github.com/PaddlePaddle/PGL/blob/develop/e…