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

目录

前言

一、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.mzph.cn/news/730479.shtml

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

相关文章

JVM-虚拟机栈概述

背景&#xff1a;由于跨平台的设计&#xff0c;java指令都是根据栈来设计的。不同平台CPU架构不同&#xff0c;所以不能设计为基于寄存器。 栈是运行时单位&#xff0c;而堆是存储的单位。即&#xff1a;栈解决程序运行的问题&#xff0c;即程序如何执行&#xff0c;或者说如何…

JavaWeb——013SpringBootWeb综合案例(事务管理、AOP)

事务&AOP 目录 事务&AOP1. 事务管理1.1 事务回顾1.2 Spring事务管理1.2.1 案例1.2.2 原因分析1.2.3 Transactional注解 1.3 事务进阶1.3.1 rollbackFor1.3.3 propagation1.3.3.1 介绍1.3.3.2 案例 2. AOP基础2.1 AOP概述2.2 AOP快速入门2.3 AOP核心概念 3. AOP进阶3.1 …

ai直播数字人:AI大模型应用开发的神奇世界

当AI技术的发展走向一个新的高峰&#xff0c;AI直播数字人逐渐成为人们关注的焦点。这种全新的数字人形态&#xff0c;通过大模型应用开发&#xff0c;带来了一个神奇世界。 在这个神奇世界里&#xff0c;AI直播数字人可以展现出与真实人类相媲美的外貌和声音。通过先进的图像…

方法中单独使用return关键字

一、return关键字的单独使用 二、示例代码 public class ReturnDemo {public static void main(String[] args) {chu(10,0);chu(10,2);}public static void chu(int a,int b){if (b 0) {System.out.println("除法出错&#xff0c;除数不能为零");return;}System.ou…

消息队列-kafka-消息发送流程(源码跟踪) 与消息可靠性

官方网址 源码&#xff1a;https://kafka.apache.org/downloads 快速开始&#xff1a;https://kafka.apache.org/documentation/#gettingStarted springcloud整合 发送消息流程 主线程&#xff1a;主线程只负责组织消息&#xff0c;如果是同步发送会阻塞&#xff0c;如果是异…

APEX开发过程中需要注意的小细节3

【问题记录】在编辑数据信息时发现辩护的数据无法保存&#xff0c;提示 “ORA-01799: 列不能外部联接到子查询” 仅展示的数据来自主表&#xff0c;这部分都是关联子表重点内容&#xff0c;编辑时无法保存 于是想将扩展表作为主表&#xff0c;在主表进行修改试试 新的报错&a…

C#实现归并排序算法

C#实现归并排序算法 以下是 C# 中的归并排序算法实现示例&#xff1a; using System;class MergeSortAlgorithm {// 合并两个子数组static void Merge(int[] arr, int left, int mid, int right){// 计算左子数组和右子数组的长度int n1 mid - left 1;int n2 right - mid;/…

C语言从入门到精通 第十二章(程序的编译及链接)

写在前面&#xff1a; 本系列专栏主要介绍C语言的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C语言教材&#xff0c;笔者认为重要的部分大多都会用粗体标注&#xf…

读《文明之光》第1册总结

人类几千年的文明史和地球的历史相比&#xff0c;实在是太短暂了&#xff0c;大约相当于几分钟和一年的关系。人类已经走过的路&#xff0c;相比今后要走的漫漫长路&#xff0c;只能算是刚刚起步。如果跳出一个个具体事件&#xff0c;站在历史的高度去看&#xff0c;我们会发现…

支小蜜校园防欺凌系统听到声音之后会自动识别吗

在校园安全领域&#xff0c;特别是在预防和应对欺凌问题上&#xff0c;校园防欺凌系统作为新兴的技术应用&#xff0c;正在受到越来越多的关注和探索。那么当这样的系统听到声音之后&#xff0c;它是否能够自动识别并作出相应反应呢&#xff1f;本文将围绕这一问题展开探讨。 …

Python通过SFTP实现网络设备配置备份

一、背景 为了防止网络设备意外损坏&#xff0c;导致配置文件无法恢复&#xff0c;可以通过将网络设备的配置文件备份到本地电脑上。 一般情况下&#xff0c;设备支持通过FTP、TFTP、FTPS、SFTP和SCP备份配置文件。其中使用FTP和TFTP备份配置文件比较简单&#xff0c;但是存在…

K线实战分析系列之十八:十字线——判断行情顶部的有效信号

K线实战分析系列之十八&#xff1a;十字线——判断行情顶部的有效信号 一、十字线二、十字线总结三、三种特殊十字线四、长腿十字线五、墓碑十字线六、蜻蜓十字线七、特殊十字线总结 一、十字线 重要的反转信号 幅度较大的下跌&#xff0c;出现一根十字线&#xff0c;正好是在…

编译内核错误 multiple definition of `yylloc‘

编译内核错误 # make ARCHarm CROSS_COMPILEarm-mix410-linux- uImageHOSTLD scripts/dtc/dtc /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss0x10): multiple definition of yylloc; scripts/dtc/dtc-lexer.lex.o:(.bss0x0): first defined here collect2: error: ld ret…

【Lazy ORM】 小工具 acw 本地客户端 你负责点击页面,他负责输出代码

介绍 wu-smart-acw-client 简称acw-client&#xff0c;是一个基于Lazy ORM定制的客户端代码生成小工具 Lazy ORM 小工具 acw 本地客户端 你负责点击页面&#xff0c;他负责输出代码安装 <dependency><groupId>top.wu2020</groupId><artifactId>wu-sma…

数据结构——lesson7二叉树 堆的介绍与实现

前言&#x1f49e;&#x1f49e; 啦啦啦~这里是土土数据结构学习笔记&#x1f973;&#x1f973; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所属专栏&#xff1a;数据结构学习笔记 &#x1f4a5;对于数据结构顺序表链表有疑问的都可以在上面数据结…

第四届信息通信与软件工程国际会议(ICICSE 2024)即将召开!

2024年第四届信息通信与软件工程国际会议&#xff08;ICICSE 2024&#xff09;将于2024年5月10-12日在中国北京举办。本次会议由北京工业大学、IEEE以及Comsoc 联合主办。随着当今社会信息化的高速发展&#xff0c;电子信息技术的应用更是随处可见。其中&#xff0c;信息通信与…

备份 ChatGPT 的聊天纪录

备份 ChatGPT 的聊天纪录 ChatGPT 在前阵子发生了不少次对话纪录消失的情况&#xff0c;让许多用户觉得困扰不已&#xff0c;也担心自己想留存的聊天记录消失不见。 好消息是&#xff0c;OpenAI 在 2023 年 4 月 11 日推出了 ChatGPT 聊天记录备份功能&#xff0c;无论是免费…

Redis什么这么快和Redis单线程模型和多线程

概述 1、完全基于内存&#xff0c;绝大部分请求是纯粹的内存操作&#xff0c;非常快速。数据存在内存中&#xff0c;类似于HashMap&#xff0c;HashMap的优势就是查找和操作的时间复杂度都是O(1)&#xff1b; 2、数据结构简单&#xff0c;对数据操作也简单&#xff0c;Redis中…

二叉树入门

这篇博客通过手动创建的一个简单二叉树&#xff0c;实现二叉树遍历&#xff0c;返回节点&#xff0c;叶子个数&#xff0c;查找结点等相关操作。 1. 二叉树的概念 二叉树不为空时&#xff0c;由根节点&#xff0c;左/右子树组成&#xff0c;逻辑结构如下&#xff0c;当二叉树…

Postman(注册,使用,作用)【详解】

目录 一、Postman 1. Postman介绍 2. 安装Postman 3. 注册帐号再使用(可保存测试记录) 4. 创建workspace 5. 测试并保存测试记录 一、Postman postman工具可以发送不同方式的请求,浏览器只能发送get请求(所有用这个工具) 在前后端分离开发模式下&#xff0c;前端技术人员…