【C++】STL- > string类(超详解!!!)

文章目录

  • 前言
  • 1、string类的出现
    • 1.1 C语言中的字符串
    • 1.2 平时使用
  • 2. 标准库中的string类
    • 2.1 string类的常用文档(重要)!!!!
    • 2.2 string类的常用接口说明(接口原型我这里就不展示了,文档中都有可以去文档中去查找)
      • 1. string类对象的常见构造
      • 2. string类对象的容量操作
      • 3. string类对象的访问及遍历操作
      • 4. string类对象的修改操作
      • 5. string类非成员函数
    • 2.3 关于string的练习题
  • 3. string类的模拟实现
    • 3.1 经典的string类问题
    • 3.2 浅拷贝
    • 3.3 深拷贝
      • 3.3.1 传统版写法的string类
      • 3.3.2 现代版写法的string类
    • 3.3 写时拷贝(了解)
    • 3.4 string类的模拟实现
  • 总结
  • 参考资料(都是一些很好的文章和文档搜索网站)


前言

提示:这里可以添加本文要记录的大概内容:

字符串是编程中非常重要的数据类型,用于存储和处理文本信息。在C++中,可以使用两种主要方式来表示和操作字符串:

  • C风格字符串:以空字符(‘\0’)结尾的字符数组,例如"Hello, world!"。这种方式比较传统,但存在一些缺点,例如不易于使用和不安全。
  • string类:C++标准模板库(STL)中提供的类,专门用于表示和操作字符串。它具有易于使用、安全等优点。
    本文将介绍C++ STL中的string类,包括其基本概念、使用方法、模拟实现以及扩展阅读等内容。

提示:以下是本篇文章正文内容,下面案例可供参考

1、string类的出现

1.1 C语言中的字符串

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些string系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可 能还会越界访问。

1.2 平时使用

在平时使用中,不管是学习还是工作都需要大量用到string,很少有人会用C库中的库函数去操作字符串,string类的出现不仅仅是为了弥补C语言的缺陷,也是为了让我们快速操作字符串

2. 标准库中的string类

2.1 string类的常用文档(重要)!!!!

在库中,甚至是string中的接口都是数量很大的,如果要求我们每一个接口都十分熟悉那显示是不可能的,那么就需要我们学习利用文档学习,下面给出一个常用文档

如果觉得页面卡顿或者是用着不习惯,也可能使用以前的旧版本,更加的简洁(标红处)
在这里插入图片描述

注意:在使用string类时,必须包含#include头文件以及using namespace std;

2.2 string类的常用接口说明(接口原型我这里就不展示了,文档中都有可以去文档中去查找)

1. string类对象的常见构造

在这里插入图片描述
主要考虑以下几个接口
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1;//构造空的string类对象,即空字符串string s2("hello cplusplus!!!");//用C-string来构造string类对象string s3(s2);//拷贝构造函数cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;return 0;
}

2. string类对象的容量操作

在这里插入图片描述

void testString2()
{string s1("hello cplusplus!!");size_t n = s1.size();cout << n << endl;cout << s1.capacity() << endl;cout << s1.empty() << endl;s1.clear();//清空字符串中的内容,使其成为空字符串,但是不会改变size的值和容量的值n = s1.size();cout << n << endl;cout << s1.capacity() << endl;cout << s1.empty() << endl;s1.reserve(100);//reserve在英文中的意思是预定的意思,相当于预定了你指定空间的容量n = s1.size();cout << n << endl;cout << s1.capacity() << endl;cout << s1.empty() << endl;s1.resize(20,'a');n = s1.size();cout << n << endl;cout << s1.capacity() << endl;cout << s1.empty() << endl;
}

注意:

  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 n = 0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小。

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

这里的迭代器大家目前可以暂时理解为指针
在这里插入图片描述
上述图片的表述有一些错误,rbegin和rend和begin、end相反,他们是反着打印,获取的也是相反的(具体可以去之前提到的文档链接去查到内容即可)

void testString3()
{string s1("hello cplusplus!!");const string s2("hello cplusplus!!");cout << s1 << " " << s2 << endl;cout << s1[0] << " " << s2[0] << endl;s1[0] = 'a';//s2[0] = 'a';//这里会发生编译错误,因为const类型对象不能修改cout << s1<<endl;string s("hello,c++");//三种遍历方式://需要注意的是,以下三种方式除了遍历打印string对象,还可以适用于遍历修改string中的字符//另外,三种方式中,对于string而言,第一种方式使用的最多// 1. for+operator[]for(size_t i = 0; i < s.size(); i++){cout << s[i]<<" ";}cout << endl;// 2.迭代器(这种方式底层大家暂时先不用明白,先了解大概怎么用,了解用法)//string::iterator it = s.begin();auto it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;// 3.范围forfor (auto& ch : s){cout << ch << " ";}}

4. string类对象的修改操作

在这里插入图片描述

void testString4()
{string s1("hello_c++");string s2("-hhh");s1.push_back('a');cout << s1 << endl;s1.append(s2);cout << s1 << endl;s1.append("xxx");cout << s1 << endl;s1 += '\0';s1 += "111";cout << s1 << endl;const char* s = s1.c_str();cout << s << endl;size_t n = s1.find("111",1);cout << n << endl;n = s1.rfind("hhh",18 );cout << n << endl;string s3 = s1.substr(0, 3);cout << s3 << endl;
}

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

5. string类非成员函数

在这里插入图片描述

**void testString5()
{string s1("hello_cpp");string s3 = s1.substr(0, 3);cout << s3 << endl;s1 = s1 + s3;cout << s1 << endl;string s2;//operator>>(cin,s2);//cout << s2 <<endl;getline(cin,s2);cout << s2 << endl;cout << ("abc" > "bbb") << endl;
}
**

上面的几个接口大家了解一下,下面的OJ题目中会有一些体现他们的使用。string类中还有一些其他的
操作,这里不一一列举,大家在需要用到时不明白了查文档即可。

2.3 关于string的练习题

  1. 题目一
  2. 题目二
  3. 题目三
  4. 题目四
  5. 题目五
  6. 题目六
  7. 题目七
  8. 题目八
  9. 题目九
  10. 题目十
  11. 题目十一

3. string类的模拟实现

3.1 经典的string类问题

上面已经对string类进行了简单的介绍,大家只要能够正常使用即可。在面试中,面试官总喜欢让学生自己
来模拟实现string类,最主要是实现string类的构造、拷贝构造、赋值运算符重载以及析构函数。大家看下以
下string类的实现是否有问题?

class string
{
public:/*string():_str(new char[1]){*_str = '\0';}*///string(const char* str = "\0") 错误示范//string(const char* str = nullptr) 错误示范string(const char* str = ""){// 构造string类对象时,如果传递nullptr指针,认为程序非法,此处断言下if(nullptr == str){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}~string(){if(_str){delete[] _str;_str = nullptr;}}private:char* _str;
};
// 测试
void Teststring()
{string s1("hello bit!!!");string s2(s1);
}

在这里插入图片描述
说明:上述string类没有显式定义其拷贝构造函数与赋值运算符重载,此时编译器会合成默认的,当用s1构
造s2时,编译器会调用默认的拷贝构造。最终导致的问题是,s1、s2共用同一块内存空间,在释放时同一块
空间被释放多次而引起程序崩溃,这种拷贝方式,称为浅拷贝。

3.2 浅拷贝

浅拷贝:也称值拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共
享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为
还有效,所以 当继续对资源进项操作时,就会发生发生了访问违规。要解决浅拷贝问题,C++中引入了深拷
贝。

3.3 深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情
况都是按照深拷贝方式提供。

在这里插入图片描述

3.3.1 传统版写法的string类

class string
{
public:string(const char* str = ""){// 构造string类对象时,如果传递nullptr指针,认为程序非法,此处断言下if (nullptr == str){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}string(const string& s): _str(new char[strlen(s._str) + 1]){strcpy(_str, s._str);}string& operator=(const string& s){if (this != &s){char* pStr = new char[strlen(s._str) + 1];strcpy(pStr, s._str);delete[] _str;_str = pStr;}return *this;}~string(){if (_str){delete[] _str;_str = nullptr;}}private:char* _str;
};

3.3.2 现代版写法的string类

class string
{
public:string(const char* str = ""){if (nullptr == str)str = "";_str = new char[strlen(str) + 1];strcpy(_str, str);}string(const string& s): _str(nullptr){string strTmp(s._str);swap(_str, strTmp._str);}// 对比下和上面的赋值那个实现比较好?string& operator=(string s){swap(_str, s._str);return *this;}/*string& operator=(const string& s){if(this != &s){string strTmp(s);swap(_str, strTmp._str);}return *this;}*/~string(){if (_str){delete[] _str;_str = nullptr;}}private:char* _str;
};

3.3 写时拷贝(了解)

写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。

引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给
计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该
对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源。

3.4 string类的模拟实现

查看完整代码

总结

本文介绍了C++ STL中的string类的基本概念和使用方法,包括:

  • string类的创建和初始化
  • 访问和修改字符串内容
  • 常用字符串操作函数
  • 模拟实现string类
  • 扩展阅读
    通过本文的学习,读者应该能够掌握string类的基本用法,并能够在实际编程中使用它来完成各种字符串操作。

参考资料(都是一些很好的文章和文档搜索网站)

  • C++ STL string类使用及实现详解: https://blog.csdn.net/xiang_bolin/article/details/136097284
  • 【C++】深入浅出STL之string类: https://blog.csdn.net/fire_cloud_1/article/details/131914378
  • std::string class in C++: https://www.geeksforgeeks.org/stdstring-class-in-c/
  • https://cplusplus.com/reference/string/string/

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

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

相关文章

前后端分离(delivery-management)部署文档

1. 前端项目:delivery-management 1.1. 前端项目打包 执行命令:npm run build 或者yarn run build,生成dist目录。 构建流程如下图: 1.2. 文件上传 将打包好的前端项目(dist目录),上传到服务器,并拷贝到nginx安装目录html目录下。 执行上传命令(sftp):put -r E:\…

展示用HTML编写的个人简历信息

展示用HTML编写的个人简历信息 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

MySQL中Binlog日志的使用

一、Binary Log介绍 MySQL 的二进制日志&#xff08;Binary Log&#xff09;是一种记录数据库更改操作的日志文件&#xff0c;它包含了所有对数据库执行的插入、更新、删除等操作的详细信息。二进制日志是 MySQL 数据库系统的核心组件之一&#xff0c;具有以下特点和作用&…

Go 语言一些常用语法编写和优化指南

Go 语言以其简洁的语法和强大的并发性能而受到开发者的喜爱。然而&#xff0c;为了充分利用 Go 的潜力&#xff0c;我们需要了解如何优化 Go 程序。本文将介绍一些常见的 Go 语言优化技巧&#xff0c;并通过实际例子进行说明。 ## 1. 利用 sync.Pool 减少内存分配 在 Go 中&a…

Windows 自带的 Linux 子系统(WSL)安装与使用

WSL官网安装教程&#xff1a; https://learn.microsoft.com/zh-cn/windows/wsl/install Windows 自带的Linux子系统&#xff0c;比用VM什么的香太多了。可以自己看官方教程&#xff0c;也可以以下步骤完成。 如果中间遇到我没遇到的问题百度&#xff0c;可以在评论区评论&#…

Redis(03)——发布订阅

基础命令 基于频道 publish channel message&#xff1a;将信号发送到指定的频道pubsub subcommand [argument [argyment]]&#xff1a;查看订阅或发布系统状态subscribe channel [channel]&#xff1a;订阅一个或多个频道的信息unsubscribe [channel [channel]]&#xff1a;退…

Java——Stream流的学习

在开发过程中&#xff0c;经常或忽略流的使用&#xff0c;导致用的不熟练&#xff0c;于是抽时间系统的学习下stream的使用&#xff0c;找了哔哩哔哩的教程跟着看看练练。 准备工作 创建Book、Aurhor实体类&#xff0c;初始化数据 public static List<Author> getAuth…

【Go语言最佳实践:永远不要启动一个停止不了的 goroutine】

前面的例子显示当一个任务时没有必要时使用 goroutine。但使用 Go 语言的原因之一是该语言提供的并发功能。实际上&#xff0c;很多情况下你希望利用硬件中可用的并行性。为此&#xff0c;你必须使用 goroutines。 这个简单的应用程序在两个不同的端口上提供 http 服务&#x…

解锁文档处理新境界:ONLYOFFICE编辑功能为开发者带来新机遇

引言 ONLYOFFICE最新发布的文档8.0版本带来了一系列引人注目的功能和优化&#xff0c;为用户提供了更强大、更高效的在线编辑体验。这次更新涵盖了多个方面&#xff0c;包括PDF表单、RTL支持、单变量求解、图表向导以及插件界面设计更新等。这些新功能不仅提升了文档处理的便利…

day 22

时间获取: 1.time time_t time(time_t *tloc); 功能: 返回1970-1-1到现在的秒数&#xff08;格林威治时间&#xff09; 参数: tloc:存放秒数空间首地址 返回值: 成功返回秒数 失败返回-1 2.localtime struct …

职业资格高级执法考试试题及答案,分享几个实用搜题和学习工具 #知识分享#微信

作为当代大学生&#xff0c;我们常常面临着繁重的学业压力和众多的学习任务。在这个信息爆炸的时代&#xff0c;如何高效地进行搜题和学习成了我们迫切需要解决的问题。幸运的是&#xff0c;随着科技的不断进步&#xff0c;我们拥有了许多方便、实用的日常搜题和学习软件。 1.…

旗舰配置,巅峰性能 | 一文玩转铁威马 『F4-424 Pro』强大的Docker虚拟机功能【附产品开箱】

旗舰配置&#xff0c;巅峰性能 | 一文玩转铁威马 『F4-424 Pro』强大的Docker&虚拟机功能【附产品开箱】 哈喽小伙伴们&#xff0c;我是Stark-C~ 开篇 记得还在两个月之前&#xff0c;我为大家介绍了国产“开箱即用”的国民专业级NAS『铁威马』&#xff1a; &#x1f53…

idea代码review工具Code Review Helper使用介绍

之前在团队里面遇到一个关于代码review的问题&#xff0c;使用gitlab自己的还是facebook的Phabricator&#xff0c;很难看到整体逻辑&#xff0c;因为业务逻辑代码可能不在这次改动范围内&#xff0c;在去源库中找不好找。针对这个刚需&#xff0c;在网上找了一个idea的代码工具…

kali安装awvs报错error creating the database

修改host文件 vim /etc/hosts 加入 127.0.0.1 kali 重启再安装即可解决

软件实例分享,操作简单美发店会员登记记账本vip会员管理系统软件教程

软件实例分享&#xff0c;操作简单美发店会员登记记账本vip会员管理系统软件教程 一、前言 以下软件程序教程以 佳易王美发店会员管理系统软件V16为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、新会员可以直接使用手.机号&#xff0c;不需…

WordPress有没有必要选择付费主题

有必要。 能用付费的&#xff0c;就尽量别用免费的。 付费主题&#xff0c;情况也比较复杂&#xff0c;先讲一下付费主题的几种情况 1、是原创付费主题。是主题制作者原创的主题。 2、是把别人的主题二次开发的付费主题。这个有些是有原始开发者授权的&#xff0c;有些就是…

解libvirt中Domain类的方法

libvirt是一个用于管理虚拟化平台的开源工具包&#xff0c;提供了对不同虚拟化技术&#xff08;如KVM、QEMU、Xen等&#xff09;的统一管理接口。在libvirt中&#xff0c;Domain类表示虚拟机&#xff08;domain&#xff09;对象&#xff0c;并提供了丰富的方法来管理虚拟机的各…

Kernelized Correlation Filters KCF算法原理详解(阅读笔记)(待补充)

KCF 目录 KCF预备知识1. 岭回归2. 循环移位和循环矩阵3. 傅里叶对角化4. 方向梯度直方图&#xff08;HOG&#xff09; 正文1. 线性回归1.1. 岭回归1.2. 基于循环矩阵获取正负样本1.3. 基于傅里叶对角化的求解 2. 使用非线性回归对模型进行训练2.1. 应用kernel-trick的非线性模型…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时&#xff0c;亚马逊会将它们关联在一起&#xff0c;从而可能导致账号被封禁或限制。 为了避免这种情况&#xff0c;许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题&#xff1f; IP代理是…

【LLVM】nsw和nuw的一个例子

nsw和nuw是LLVMIR提供给二元运算的flag。分别表示not signed wrap和not unsigned wrap。在LLVM2.6的更新日志中表述如下&#xff1a; The add, sub and mul instructions now support optional “nsw” and “nuw” bits which indicate that the operation is guaranteed to n…