C++string类

news2024/12/23 20:17:06

📟作者主页:慢热的陕西人

🌴专栏链接:C++

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

本博客主要内容讲解了C++中的string类以及类内的一些常用函数

C++string类

文章目录

  • C++string类
    • @[toc]
    • Ⅰ. 为什么要学习string类
    • Ⅱ. 标准库中的string类
      • Ⅱ. Ⅰ. string类的了解
      • Ⅱ. Ⅱ. string类中常用接口说明

Ⅰ. 为什么要学习string类

首先我们在C语言中有字符串的概念,是一些以\0结尾的字符的集合,而且C语言中也有很多和字符串相关的函数例如:strstr等,但是C语言中是将这些函数和字符串是分离开来的,这不符面向对象变成的思想,而且空间管理是交给用户自己来处理,非常容易出现越界问题。所以在C++中将字符串和字符串相关的函数集成在一个类里面,提高编程效率。

Ⅱ. 标准库中的string类

Ⅱ. Ⅰ. string类的了解

这里首先附上string类的文档string - C++ Reference (nonplussing)

  • 字符串是表示字符序列的类

  • 标准的字符串类提供了对此类对象的支持,其接口类似于标准字容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性

  • string类是使用char(即作为它的字符类型,使用它的默认char_traits和allocator(分配器)类型(关于模板的更多信 息,请参阅basic_string)

  • string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits 和allocator(分配器)作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。

  • 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-81)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作

    总结:

    • string是表示字符串的字符串类
    • 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作
    • string在底层实际是:basic_string模板类的别名,typedef basic_string string
    • 不能操作多字节或者变长字符的序列

Ⅱ. Ⅱ. string类中常用接口说明

①string类对象的常见构造:

当然库中不止以下这些可以点击下面的constuct链接详细阅读。

(construct)函数名称功能说明
string()Constructs an empty string, with a length of zero characters.
string (const string& str);Constructs a copy of str.(拷贝构造)
string (size_t n, char c);Fills the string with n consecutive copies of character c.
string (const char* s);Copies the null-terminated character sequence (C-string) pointed by s

例如:

void Teststring()
{
	string s1; // 构造空的string类对象s1
	string s2("hello bit"); // 用C格式字符串构造string类对象s2
	string s3(s2); // 拷贝构造s3
}

②string类对象的容量操作:

函数名称功能说明
sizeReturns the length of the string, in terms of bytes(我们更常用这个相比于length2
lengthReturns the length of the string, in terms of bytes
capacityReturns the size of the storage space currently allocated for the string, expressed in terms of bytes
reserveRequests that the string capacity be adapted to a planned change in size to a length of up to n characters
clearErases the contents of the string, which becomes an empty string (with a length of 0 characters).
resizeResizes the string to a length of n characters.
emptyReturns whether the string is empty (i.e. whether its length is 0).

注意:

  • clear()只是将string中有效字符清空,不改变底层空间大小。

  • resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字 符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的 元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变。

  • reserve(size_t res_arg = 0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小

void Teststring1()
{
	// 注意:string类对象支持直接用cin和cout进行输入和输出
	string s("hello, bit!!!");
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
	s.clear();
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	// 将s中有效字符个数增加到10个,多出位置用'a'进行填充
	// “aaaaaaaaaa”
	s.resize(10, 'a');
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	// 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
	// "aaaaaaaaaa\0\0\0\0\0"
	// 注意此时s中有效字符个数已经增加到15个
	s.resize(15);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	// 将s中有效字符个数缩小到5个
	s.resize(5);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;
}

③string类对象的访问及遍历操作

函数名称功能说明
operator[ ]Returns a reference to the character at position pos in the string.
begin + endbegin: Returns an iterator pointing to the first character of the string. end: Returns an iterator pointing to the past-the-end character of the string.
rbegin + rendrbegin: Returns a reverse iterator pointing to the last character of the string. rend: Returns a reverse iterator pointing to the theoretical element preceding the first character of the string
范围forC++11支持更简洁的范围for的新遍历方式(底层还是迭代器(iterator))

范围for例子:

int arr[5] = {10, 20, 30, 40, 50};
for (int x : arr) {
    // 打印每一个元素
    std::cout << x << " ";
}

访问元素及遍历例子:

	string s("hello xupt");
	// 3种遍历方式:
	// 需要注意的以下三种方式除了遍历string对象,还可以遍历是修改string中的字符,
	// 另外以下三种方式对于string而言,第一种使用最多
	// 1. for+operator[]
	for (size_t i = 0; i < s.size(); ++i)
		cout << s[i] << endl;

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

	// string::reverse_iterator rit = s.rbegin();
	// C++11之后,直接使用auto定义迭代器,让编译器推到迭代器的类型
	auto rit = s.rbegin();
	while (rit != s.rend())
		cout << *rit << endl;

	// 3.范围for
	for (auto ch : s)
		cout << ch << endl;

④string类对象的修改操作:

函数名称功能说明
push_backAppends character c to the end of the string, increasing its length by one.
appendExtends the string by appending additional characters at the end of its current value:
operator+=Extends the string by appending additional characters at the end of its current value:
c_strReturns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object.
find + nposfind: Searches the string for the first occurrence of the sequence specified by its arguments. npos :Maximum value for size_t static const size_t npos = -1;
rfindSearches the string for the last occurrence of the sequence specified by its arguments.
substrReturns a newly constructed string object with its value initialized to a copy of a substring of this object.

注意:

  • 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般 情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  • 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好(因为扩容是需要一定的时间代价的,提前扩容的话,就可以避免反复扩容的情况,从而达到节省时间的目的)。
	string str;
	str.push_back(' ');   // 在str后插入空格
	str.append("hello");  // 在str后追加一个字符"hello"
	str += 'b';           // 在str后追加一个字符'b'   
	str += "it";          // 在str后追加一个字符串"it"
	cout << str << endl;
	cout << str.c_str() << endl;   // 以C语言的方式打印字符串

	// 获取file的后缀
	string file("string.cpp");
	size_t pos = file.rfind('.');
	string suffix(file.substr(pos, file.size() - pos));
	cout << suffix << endl;

	// npos是string里面的一个静态成员变量
	// static const size_t npos = -1;

	// 取出url中的域名
	string url("http://www.cplusplus.com/reference/string/string/find/");
	cout << url << endl;
	size_t start = url.find("://");
	if (start == string::npos)
	{
		cout << "invalid url" << endl;
		return;
    }

⑤string类非成员函数

函数功能说明
operator+3Returns a newly constructed string object with its value being the concatenation of the characters in lhs4 followed by those of rhs.4
operator>>Extracts a string from the input stream is, storing the sequence in str, which is overwritten (the previous value of str is replaced).
operator<<Inserts the sequence of characters that conforms value of str into os.
getlineExtracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)).
relational operators Performs the appropriate comparison operation between the string objects lhs and rhs.

⑥vs和g++下string结构的说明

注意:下述结构都是在32位平台下验证的。

  • vs下的string结构:

    string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:

    • 当字符串长度小于16时,使用内部固定的字符数组来存放
    • 当字符串长度大于等于16时,从堆上开辟空间
    union _Bxty
    { 	// storage for small buffer or pointer to larger one
     	value_type _Buf[_BUF_SIZE];
     	pointer _Ptr;
     	char _Alias[_BUF_SIZE]; // to permit aliasing
    } _Bx;
    
    

    这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内 部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。

    其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量

    最后:还有一个指针做一些其他事情。

    故总共占16+4+4+4=28个字节。

  • g++下string的结构

    G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指 针将来指向一块堆空间,内部包含了如下字段:

    • 空间总大小
    • 字符串有效长度
    • 引用计数
    struct _Rep_base
    {
     size_type _M_length;
     size_type _M_capacity;
     _Atomic_word _M_refcount;
    };
    
    • 指向堆空间的指针,用来存储字符串.

到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正

在这里插入图片描述


  1. 是一种字符编码方式详细了解可查看这个文章Unicode、UTF-8、UTF-16 终于懂了 - 知乎 ↩︎

  2. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。 ↩︎

  3. 尽量少用,因为传值返回,会导致拷贝效率低 ↩︎

  4. 分别是运算符左侧和右侧的值 ↩︎ ↩︎

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

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

相关文章

k8s_3节点集群部署

背景 近期想在自己电脑上部署一套3节点K8s 作为自己平时的学习测试环境。 本来想看一下有没有比较便捷的部署方式如&#xff1a; rancherdesktop: https://docs.rancherdesktop.io/zh/next/getting-started/installation/ sealos: https://www.sealos.io/docs/getting-started…

【超算/先进计算学习】日报3

目录 今日已完成任务列表遇到的问题及解决方案任务完成详细笔记作业管理系统 slurm作业管理系统及常用用户命令节点状态查询/作业提交命令作业队列查询/作业取消命令任务练习 调试器 GDB实时调试core 文件调试 对自己的表现是否满意简述下次计划其他反馈 今日已完成任务列表 4-…

Spring的体系结构

Spring的体系结构 一、Spring简介1. Spring介绍1.1 为什么要学1.2 学什么1.3 怎么学 2. 初识Spring2.1 Spring家族2.2 Spring发展史 3. Spring体系结构3.1 Spring Framework系统架构图3.2 Spring Framework课程学习路线 4. Spring核心概念4.1 目前我们代码存在的问题4.2 核心概…

『Linux从入门到精通』第 ⑫ 期 -深入了解冯诺依曼体系结构与操作系统(Operator System)

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f337;计算机之父——冯诺依曼&#x1f337;冯诺依曼体系结构&#x1f33a;木桶效应 &#x1f337;操作系统(Operator System)&#x1f33a;如何理解操作系统&#x1f33a;系统调用和库函数概念 &#x1f490;专栏导…

论文结构商讨

论文查重 pass软件 提出问题 1、由于选取的算法太多了&#xff0c;不知道是简单介绍&#xff0c;还是深入介绍 希望找到一个具体的模板 2、数据库要是用一个就在前面介绍&#xff0c;用不一样的就在每章里面分别介绍 4、数据集介绍放在那个具体位置&#xff1f; 如果可以画出…

蓝精灵事件来袭: 深受喜爱的蓝色角色来 Web3 啦!

起源于漫画并成为国际知名的卡通和电影明星的蓝色x小家伙正在进入 NFT 舞台。 作者&#xff1a;Coindesk——Toby Bochan 因漫画、卡通片和电影而闻名的热门动画系列“蓝精灵”正在展开新的冒险&#xff0c;由蓝精灵协会推出一系列新的非同质化通证&#xff08;NFT&#xff09;…

汽车ECU的内部构成与功能模块

摘要&#xff1a; ECU作为与外部通信的接口&#xff0c;为了通过微控制器运算实现符合实际状态的最佳控制&#xff0c;需要检测外部状态的输入手段及实际控制驱动的输出手段。 1. 常规功能模块 ① 电源&#xff1a;向ECU内的各模块提供稳定的电压&#xff08;5V、3V等&#xf…

sequelize + Nodejs + MySQL 的简单用法

How to Use Sequelize ORM in NodeJS - Tutorial 1 Sequlize 简介 Sequelize 是最流行的可以与 Nodejs 一起使用的一种关系数据库 ORM (Object-relational mapping 对象关系映射)&#xff0c;Mongoose 是 MongoDB 的 ORM. Sequelize 的作用&#xff0c;简单地说&#xff0c;就…

Netty编解码器,Netty自定义编解码器解决粘包拆包问题,Netty编解码器的执行过程详解

文章目录 一、编解码器概述1、编解码器概述2、编码器类关系图3、解码器类关系图 二、以编解码器为例理解入站出站1、Server端2、Client端3、编解码器3、执行查看结果4、注意事项 三、Netty其他内置编解码器1、ReplayingDecoder2、其他编码器3、内置编解码器处理粘包拆包问题 四…

[LeetCode复盘] LCCUP‘23春季赛 20230422

[LeetCode复盘] LCCUP23春季赛 20230422 一、总结二、 1. 补给马车1. 题目描述2. 思路分析3. 代码实现 三、2. 探险营地1. 题目描述2. 思路分析3. 代码实现 四、 3. 最强祝福力场1. 题目描述2. 思路分析3. 代码实现 五、 4. 传送卷轴1. 题目描述2. 思路分析3. 代码实现 六、 5…

REDIS03_AOF概述、工作流程、写回策略、正常异常流程、重写机制、配置文件详解

文章目录 ①. AOF - 概述作用②. AOF - 工作流程③. 缓冲区 - 写回策略④. 配置文件说明(6 VS 7)⑤. 正常、异常恢复⑥. AOF - 优劣势⑦. AOF - 重写机制⑧. AOF优化配置项详解⑨. RBD和AOF共存模式 ①. AOF - 概述作用 ①. 官网介绍 ②. 以日志的形式来记录每个写操作,将Red…

解决RabbitMQ的The channelMax limit is reached. Try later.

The channelMax limit is reached. Try later.顾名思义就是channel达到数量限制 查看源码得出 大概意思就是&#xff1a; 默认最大通道数&#xff1b;2047&#xff0c;因为它在服务器端是第2048个&#xff0c;每个连接用于协商和错误通信。 也可以在rabbitmq的管控台看出 总结…

单页面与路由

目录 &#xff08;一&#xff09;什么是SPA应用&#xff1f; &#xff08;二&#xff09;路由 &#xff08;1&#xff09;什么是路由&#xff1f; &#xff08;2&#xff09;路由的分类 &#xff08;3&#xff09;路由的安装和使用 &#xff08;三&#xff09;、路由的使…

微服务 - 搭建Consul集群服务,Consul配置中心

传统配置文件的弊端 静态化配置&#xff0c;例如env文件配置文件无法区分环境配置文件过于分散历史版本无法查看 配置中心如何解决的呢?配置中心的思路是把项目中的配置参数全部放在一个集中的地方来管理&#xff0c;并提供一套标准的接口&#xff0c;当各个服务需要获取配置…

d2l 使用attention的seq2seq

这一章节与前面写好的function关联太大&#xff0c;建议看书P291. 这章节主要讲述了添加attention的seq2seq,且只在decoder里面添加&#xff0c;所以全文都在讲这个decoter 目录 1.训练 2.预测 1.训练 #save class AttentionDecoder(d2l.Decoder):"""带有注…

HTTP与HTTPS相关介绍(详细)

HTTP与HTTPS相关介绍 HTTP与HTTPS简述HTTPS和HTTP的区别主要如下HTTPS的工作原理前言工作步骤总结 HTTPS的缺点SSL与TLSSSL&#xff1a;TLS&#xff1a;TLS和SSL的关系 对称加密与非对称加密对称加密非对称加密 HTTP与HTTPS简述 超文本传输协议&#xff08;Hyper Text [Transf…

如何无侵入地引入第三方组件?

做java开发的小伙伴都知道&#xff0c;java的生态比较繁荣&#xff0c;有各种各样的第三方组件来满足我们日常的开发需求。很多常用的中间件(redis&#xff0c;kafka等)都提供java的开发接口&#xff0c;而且这些接口通常会被封装成比较好用的组件来满足我们使用这些中间件的场…

SpringBoot集成MyBatis-yml自动化配置原理详解

SpringBoot集成MyBatis-yml自动化配置原理详解 简介&#xff1a;spring boot整合mybatis开发web系统目前来说是市面上主流的框架&#xff0c;每个Java程序和springboot mybatis相处的时间可谓是比和自己女朋友相处的时间都多&#xff0c;但是springboot mybatis并没有得到你的真…

RabbitMQ--详情概述

一、消息队列(Rabbit Message Queue) 1、概念 消息队列是一种应用之间的通信方式&#xff0c;消息发送之后可以立即返回&#xff0c;由消息系统来确保消息的可靠传递。消息发布者只发布消息到MQ&#xff0c;消息使用者值从MQ中拿消息&#xff0c;两者不知道对方的存在。 简…

Sentinel——限流规则

目录 快速入门 簇点链路 案例 流控模式 流控模式——关联 流控模式——链路 案例 流控效果 流控效果——warm-up 流控效果——排队等待 热点参数限流 快速入门 簇点链路 簇点链路&#xff1a;就是项目内的调用链路&#xff0c;链路中被监控的每个接口就是一个资源。…