【C++ STL详解】——string类

news/2024/4/13 11:42:07/文章来源:https://blog.csdn.net/m0_73470633/article/details/136410893

目录

前言

一、string类对象的常见构造

二、string类对象的访问及遍历

1.下标+【】(底层operator【】函数)

​编辑

2.迭代器

3.范围for

4.at

5.back和front

三、string类对象的容量操作

1.size 和 length

2.capacity

3.empty

4.clear

5.resize(调整当前字符串的大小)

6.reserve(改变当前容量的大小)

7.shrink_to_fit(缩容)

四、string类对象的修改操作

1.operator+=(尾部追加)

2.append(拼接)

3.push_back(尾插)

4.insert(插入)

5.erase(删除)

6.replace(替换)

7.swap(交换)

五、string的查找

1.find(左闭右开区间,正向查找)

2.rfind(反向查找)

六、string的截取

substr:左闭右开

七、string与字符串的转化

1.字符串转化为string

2.string转为字符串

八、非成员函数重载

1.operator<<和operator>>(输入输出运算符重载)

2.relational operators (string)


前言

好了,老铁们,前面我们对C++的一些基础语法以及一些注意事项都有了一定的了解!那么接下来我们将要进入一个崭新的世界,就是对STL库的学习!对于STL的学习核心有三点:熟用、明理(底层实现)、扩展!下面先来看看string类

  • 通过文档可以看出string是表示字符串的字符串类
  • 底层实际是:basic_string模板类的别名,typedef  basic_string<char, char_traits, allocator>stirng;
  • 使用string类时,必须包含#include头文件以及using namespace std;

如果想要了解更多,关于string类的说明,大家可以参照这个文档:string类

一、string类对象的常见构造

string();   //构造一个空字符串,长度为0(默认构造)string (const string& str); //拷贝构造string (const char* s); //复制s所指向的字符序列string (const char* s, size_t n); //复制所指向的字符序列的前n个字符string (size_t n, char c);      //复制n个字符Cstring (const string& str, size_t pos, size_t len = npos);
//复制str中从字符位置pos开始并跨越len个字符的部分(如果str太短或len为string::npos,则复制到str的末尾)

示例:

	string s0;                         //构造空串string s1("is string");            //复制is stringconst char* s = "hello string";string s2(s);                      //复制"hello string"string s3(s, 3);                   //复制"hello string"前3个字符string s4(10, '#');                //复制10个#string s5(s1, 0, 5);               //从s1中的位置0开始跨越5个字符的部分,左闭右开区间cout << s0 << endl;cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;

二、string类对象的访问及遍历

1.下标+【】(底层operator【】函数)

string s1("hello string");
for (int i = 0; i < s1.size(); i++)
{cout << s1[i] << ' ';//底层写法:cout << s1.operator[](i) << endl;
}

2.迭代器

  • 正向迭代器(begin+end)

begin函数:返回一个指向字符串第一个字符的迭代器

end函数:返回一个指向字符串最后一个字符的下一个位置(即为'\0')的迭代器

这里要注意到,迭代器的函数都会有两个形式一个是非const,一个是const!会根据对象类型的不同去选择不同的函数!

示例:

string s1("hello string");
string::iterator it = s1.begin();
while (it != s1.end())
{cout << *it << ' ';it++;
}
	const string s2("hello string");string::const_iterator it = s2.begin();while (it != s2.end()){cout << *it << ' ';it++;}//    const对象返回的是const迭代器,所以不能用普通迭代器去接受

  • 反向迭代器(rbegin+rend)

rbegin函数:返回一个指向字符串最后一个字符的反向迭代器

rend函数:返回一个指向字符串第一个字符前理论元素的反向迭代器(被认为是反向端)

示例:

	string::reverse_iterator it1 = s1.rbegin();while (it1 != s1.rend()){cout << *it1 << ' ';it1++;}

可以看出,其实就是反向输出!但是要注意它是反向++的

3.范围for

for (auto a : s1)
{cout << a << ' ';
}

其实,范围for底层就是个迭代器!!!

4.at

	for (int i = 0; i<s.length(); ++i){cout << s.at(i) << " ";}

注意:这里是at(),不是方括号[],和第一个operator功能类似,但是唯一的不同在于,两者对于越界的处理不同!

5.back和front

cout << s.back() << endl;;//访问到最后一个字符
cout << s.front();//访问第一个字符

注意:它访问到的同时,还可以进行修改!

s.back() = 'A';//最后一个元素变为A
s.front() = 'B';//第一个变为B
cout << s.back() << ' ';
cout << s.front();

三、string类对象的容量操作

1.size 和 length

string s1("hello string");
cout << s1.size() << endl;
cout << s1.length() << endl;//返回字符串有效长度

size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。他们得到的结果并不一定等于capacity!

2.capacity

s1.capacity();//返回总空间的大小

3.empty

 s1.empty();//检测字符串是否为空,为空就返回true,否则返回false

4.clear

 s1.clear();//擦除字符串内容,使其变为空字符串,并不改变底层空间的大小

5.resize(调整当前字符串的大小)

会出现以下两种情况:

        ①如果n小于当前字符串的长度,那么他就会将当前长度缩短到n个字符的长度,并将第n个字符以外的其他部分全部删除!

        ②如果n大于当前字符的长度,那么就会将大小扩大到n,扩大的部分如果有字符c,那就拿字符C填充,没有就拿字符'\0'补充!

6.reserve(改变当前容量的大小)

规则如下:

  • 如果n大于当前的容量,那么容量就会扩充到n甚至更大
  • 如果n小于当前容量,那就什么都不做
  • 这个函数不会影响字符串的长度,也不会改变其内容

7.shrink_to_fit(缩容)

规则:调整其capacity以适应它的size

四、string类对象的修改操作

1.operator+=(尾部追加)

如上图,有常见的三种重载形式,功能就是:通过在当前字符串的末尾附加额外字符来扩展字符串

string s("hello string");
s += " ";
s += "!!!!!!";
cout << s << endl;
string s2 = ("  ggggg  ");
s += s2;
cout << s << endl;

2.append(拼接)

这个函数的功能:也是上面的一样,追加,额……但是重载函数有很多,但是常用的就三种:

string& append(const string& str);

string& append(const char*s);

string& append(size_t  n,char c);

	string s("hello string");s.append(" ");s.append("sjda");s.append(10, 'A');cout << s << endl;

3.push_back(尾插)

功能:将字符c追加到字符串的末尾,使其长度增加1。

s.push_back('A');

4.insert(插入)

额……还是有点多,其实常用的就一个:在pos位置前插入字符串

string& insert(size_t pos,const char *s);

int main()
{string s("hello string");s.insert(5, "hhhhhe");//在第五个位置前,插入字符串“hhhhhe”cout << s << endl;return 0;
}

5.erase(删除)

规则:擦除字符串中从字符位置pos开始并跨越len字符的部分(如果内容太短或len为string::npos,则擦除直到字符串末尾)。

s.erase(0, 5);//删除从第0个位置开始的5个字符
cout << s << endl;//迭代器
s.erase(s.begin() + 1);
cout << s << endl;//删除第二个位置的值//删除区间的元素,区间为左闭右开[first,last)
s.erase(s.begin() + 1, s.end() - 1);
cout << s << endl;

6.replace(替换)

其实也有很多个,hh,大家想看完整的可以自己点进链接,下面两种是最常用的

  • String& replace (size_t pos, size_t len, const char* s);
cout << s.size() << endl;
s.replace(0, 4, "AAAAAAAAA");//从0位置开始的4个字符替换成特定字符串,
//但是有一点需要注意,字符串的内容的长度可以任意,随之大小也会改变cout << s << endl;
cout << s.size() << endl;

  • String& replace (size_t pos, size_t len, size_t n, char c);
cout << s.size() << endl;
cout << s.capacity() << endl;s.replace(0, 4, 100, 'V');//从0位置开始的4个字符替换为100个字符‘V’
cout << s << endl;
cout << s.size() << endl;
cout << s.capacity() << endl;

编译器会按照自己特定的方式进行扩容,在LInux下又是另外的扩容方式!!

需要注意:

上面的尾部追加字符s.append(1,c) / s.push_back(c) /s+='c'其实实现的差不多,但是实际应用中使用+=比较多,它不仅仅可以连接字符,还可以连接字符串

②实际上insert/erase/replace,但数据很大时,需要挪动大量的数据,效率太低,能少用就尽量少用!!!

③对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

7.swap(交换)

        对于这个交换函数,其实在STL库里面有两个,一个是作为string类的成员函数,一个是全局的函数,谁都可以用的!

int main()
{string s1("hello s1");string s2("hello s2");//用string里面的交换函数s1.swap(s2);cout << s1 << endl;cout << s2 << endl;cout << endl;//全局的swapswap(s1, s2);cout << s1 << endl;cout << s2 << endl;return 0;
}

五、string类的查找

1.find(左闭右开区间,正向查找)

功能:从字符串pos位置(不写默认是0)开始往后找字符c,返回的是第一个匹配的第一个字符的位置。
如果没有找到匹配项,函数返回string::npos(-1)。(n
pos是一个静态成员常量值,具有size_t类型元素的最大可能值

注意:他们都是const成员函数,就是说可读不可写,仅仅只是查找,遍历访问操作它是可以改变值的,也就是可读可写!

int main()
{string s("http://baidu.com/");string s2("bai");//find(string,pos)返回第一个匹配的位置,也就是b的位置size_t pos1= s.find(s2);cout << pos1 << endl;//find(str,pos)size_t pos2 = s.find("com");cout << pos2 << endl;//find(字符,pos)size_t pos3 = s.find('u');cout << pos3 << endl;return 0;
}

这里没有演示第三个重载函数,因为它其实和第二个重复了,直接用第二个就好了!

2.rfind(反向查找)

功能:从pos位置(默认是npos位置)开始向前查找字符串或者字符,找到就返回它的位置,这个位置是从前先后数的;如果没有找到就返回npos(换个方向理解就是:找到最后一次匹配的第一个字符的位置

注意:这里的第三个重载函数其实和find的情况是一样的,重复了第二个,感觉有点多余(个人吐槽)

六、string类的截取

substr:左闭右开

功能:从pos位置开始,截取n个字符,返回的结果是一个新的字符串对象,这个新对象的内容就是使用截取到子字符串去初始化!

所以这个实际上可以和find去结合使用

七、string类与一些类型的转化

1.字符串转化为string

这个很简单,其实就是第一部分的常见构造的方式!!

string s1("hello string");char str[] = "hello string";
string s2(str);

2.string转为字符串

这个可以使用string类中的c_str或者date

c_str: const char *c_str() const;

data: const char *data() const;

区别:在C++98中,C_str转化过来的,在末尾会加上"\0",但是data不会!在C++11中,两者都会加!

string s("https://cplusplus.com/reference/string/string/rfind/");const char* str1 = s.c_str();
const char* str2 = s.data();
cout << str1 << endl;
cout << str2 << endl;

3.内置类型转化为string

double d = 40.25;
string s1 = to_string(d);

还可以是其他的内置类型哦!!!!!

4.string转化为内置类型

string s1("45.630");
double d = stod(s1);

八、非成员函数重载

1.operator<<和operator>>(输入输出运算符重载)

Istream& operator>> (Istream& is, string& str);输入运算符重载

Ostream& operator<< (Ostream& os, const string& str);输出运算符重载

string s;
cin>>s;
cout<<s<<endl;

因为有了这个重载函数,所以可以使用cin和cout输入输出string类!

2.relational operators (string)(大小比较)

这是string类的关系操作符,包括==,!=,<,<=,>,>=。重载的函数,支持string类和string类、string类和字符串之间的比较!

int main()
{string s1("hello");string s2("hikklkl");//string 和stringcout << (s1 == s2) << endl;cout << (s1 != s2) << endl;cout << (s1 < s2) << endl;cout << (s1 <= s2) << endl;cout << (s1 > s2) << endl;cout << (s1 >= s2) << endl;cout << endl;//string和字符串const char* s3 = "hella";cout << (s1 == s3) << endl;cout << (s1 != s3) << endl;cout << (s1 < s3) << endl;cout << (s1 <= s3) << endl;cout << (s1 > s3) << endl;cout << (s1 >= s3) << endl;return 0;
}

十分的爽!

3.getline(获取一行字符串)

这个函数的存在,其实就是因为cin和scanf的一点小缺陷,看代码

发现了什么,明明输入的A B,可是出来的却是A,其实就是因为cin和scanf在遇到空格时就会停止读取后面的字符,而后面的字符实际上放在缓冲区里!在读取一次看看

此时,A B才能完全输出!有了getline就很方便!

这个函数也是有两个用法的:

如果有界定符,那就读取到界定符为止,后面的字符直接丢弃!

string s;
getline(cin, s,'r');//读到分隔符‘r’为止
cout << s << endl;

②如果没有,那就是默认到‘\0’


好了,感谢大家的阅读!这部分内容有点小多,大家如果想要查看原文档可以点击string文档!

其实实际上用到不多!!题中见分晓!

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

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

相关文章

Python编程实验六:面向对象应用

目录 一、实验目的与要求 二、实验内容 三、主要程序清单和程序运行结果 第1题 第2题 四、实验结果分析与体会 一、实验目的与要求 &#xff08;1&#xff09;通过本次实验&#xff0c;学生应掌握类的定义与对象的创建、类的继承与方法的覆盖&#xff1b; &#xff08;2…

接收端编程、UDP编程练习、wireshrak抓包工具、UDP包头

我要成为嵌入式高手之3月6日Linux高编第十六天&#xff01;&#xff01; ———————————————————————————— 学习笔记 接收端 recvfrom #include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, si…

一文学会搭建 cli 脚手架工具

文章目录 设置工具命令package.json bin 字段注释&#xff1a;#!/usr/bin/env node设置环境变量 接收命令选项参数process 实现commander 命令行交互&#xff1a;inquirer下载项目模板&#xff1a;download-git-repo执行额外命令&#xff1a;自动安装依赖child_processexeca 体…

Mybatis-Plus——05,乐观锁(新注解)

乐观锁&#xff08;新注解&#xff09; 一、数据库添加一个字段二、实体类添加version注解三、注册乐观锁插件四、测试一下4.1成功的乐观锁4.2失败的乐观锁————————创作不易&#xff0c;笔记不易&#xff0c;如觉不错&#xff0c;请三连&#xff0c;谢谢~~ 乐观锁实现方…

Flask python开发篇: 写一个简单的接口

第一步&#xff1a;新建flask项目 参考使用pycharm新建一个项目 打开pycharm&#xff0c;根据下面图中箭头顺序&#xff0c;新建一个flask的项目&#xff1b; 第二步&#xff1a;运行项目&#xff0c; 安装成功以后&#xff0c;会有个app.py文件&#xff0c;打开以后&#…

Kali Linux 2024.1

Kali Linux 2024.1刚刚发布&#xff0c;标志着这个备受欢迎的安全重点Linux发行版在今年的首次重大更新。以其先进的渗透测试和安全审计功能而闻名&#xff0c;它是安全专业人员和爱好者的首选工具。 Kali 2024.1 亮点 本次发布由 Linux 内核 6.6 提供支持&#xff0c;突出了…

借着ChatGPT的人机交互聊聊长连接

ChatGPT这两年可谓风靡全球&#xff0c;尤其是最近Sora视频模型的横空出世以及claude 3模型所具备的浅意识&#xff0c;更是像打开了新世界的大门。本文就从ChatGPT的网页聊天开始聊起&#xff08;有蹭热度之嫌&#xff0c;哈哈&#xff09;&#xff0c;聊聊长连接的发展历程和…

148个Chatgpt关键词汇总-有爱AI实战教程(二)

演示站点&#xff1a; https://ai.uaai.cn 技能模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 导读&#xff1a;在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c;如…

来说说看到的求职路上可以提高的地方——简历

要进行求职的时候应该遇到的第一件事情就是简历。 随着看到的简历越来越多&#xff0c;也发现了一些问题&#xff0c;来开个帖子来说说这些问题。 格式 让参加面试的人最头疼的地方就是简历格式没有空格。 最近发现好多人的简历格式上都不空格&#xff0c;很多内容完全都在…

IntelliJ IDEA自定义关闭当前文件的快捷方式

前言 idea中关闭当前标签页的默认快捷键是CtrlF4,这个组合键在键盘上操作起来很是不方便&#xff0c;我们可以在设置中自定义自己习惯的快捷方式。 自定义步骤 要在 IntelliJ IDEA 中将关闭当前文件的快捷方式设置为 Alt Q&#xff0c;请按照以下步骤操作&#xff1a;打开 …

Android应用界面

概述&#xff1a;由于学校原因&#xff0c;估计会考&#xff0c;曹某人就浅学一下。 目录 View概念 创建和使用布局文件 相对布局 线性布局 水平线性布局 垂直线性布局 表格布局 帧布局 扁平化布局 Android控件详解 AdapterView及其子类 View概念 安卓中的View是所…

Qt初识 - 编写Hello World的两种方式 | 对象树

目录 一、通过图形化方式&#xff0c;在界面上创建出一个控件 二、通过代码方式&#xff0c;创建Hello World 三、Qt 内存泄漏问题 (一) 对象树 一、通过图形化方式&#xff0c;在界面上创建出一个控件 创建项目后&#xff0c;打开双击forms文件夹中的ui文件&#xff0c;可…

Mysql8的优化(DBA)

Mysql8的优化 1、Mysql的安装优化1.1 修改配置参数&#xff08;命令行、配件文件&#xff09;1.1.1 命令行修改配置参数1.1.2 参数持久化1.1.3 Mysql多实例启动&#xff0c;以及配置密码文件 1.2 查询表的相关参数&#xff0c;以及表空间管理 2、Mysql高级优化&#xff08;SQL&…

CNC机加工引入复合机器人可以提高生产效率,降低成本

CNC加工企业在过去依赖大量的人工来完成生产线上的各项任务&#xff0c;包括CNC机床的上下料、物料搬运以及部分装配工作。然而&#xff0c;随着产能需求的不断增长和人工成本的持续上升&#xff0c;企业逐渐意识到自动化升级的重要性与迫切性。 面临的挑战与需求&#xff1a; …

【DUSt3R】2张图2秒钟3D重建

【DUSt3R】2张图2秒钟3D重建 1. DUSt3R是一种用于稠密和无约束立体三维重建的方法,其实现步骤如下:2. 实际运行效果3. 运行结果4. 自问自答4.1 为社么这里要是使用transform模型呢?4.2 CroCo(通过跨视图完成3D视觉任务的自我监督预训练的一个研究)在DUSt3R的作用是什么,为…

云计算项目十:ES集群安装|部署kibana

ES集群安装 部署ES集群&#xff0c;用于ELK日志分析平台的构建 es-0001 主机更改 /etc/hosts [rootes-0001 ~]# vim /etc/hosts 192.168.1.71 es-0001 192.168.1.72 es-0002 192.168.1.73 es-0003 192.168.1.74 kibana 192.168.1.75 logstash # 将最新的/etc/hosts配置文件更…

javaSE-----继承和多态

目录 一.初识继承&#xff1a; 1.1什么是继承&#xff0c;为什么需要继承&#xff1a; 1.2继承的概念与语法&#xff1a; 二.成员的访问&#xff1a; 2.1super关键字 2.2this和super的区别&#xff1a; 三.再谈初始化: 小结&#xff1a; 四.初识多态&#xff1a; 4.1多…

Visual Studio 2019重装vs2019打不开.netcore项目

无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBuild 的 17.4.0 版本。当前可用的 MSBuild 版本为 16.11.2.50704。请将在 global.json 中指定的 .NET SDK 更改为需要当前可用的 MSBuild 版本的旧版本。 无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBui…

go语言添加代理

LiteIDE 工具->管理 https://mirrors.aliyun.com/goproxy/或https://goproxy.cn,direct 命令行 go env -w GOPROXYhttps://goproxy.cn,direct

C.C语言分支和循环语句

文章目录 一. 什么是语句 二. 分支语句&#xff08;选择结构&#xff09; 2.1. if 语句 2.1.1. 语法结构 2.1.2. 悬空else 2.1.3. 书写形式的对比 2.1.4. 练习 2.2. switch 语句 3.2.1. 语法结构 3.2.2. 在switch语句中的 break 3.2.3. default子句 3.2.4. 练习 三…