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

news2024/12/23 13:18:36

目录

前言

一、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个字符C

string (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 string
	const 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;

	//全局的swap
	swap(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 和string
	cout << (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.coloradmin.cn/o/1501353.html

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

相关文章

Xilinx 7系列 FPGA硬件知识系列(九)——FPGA的配置

1.3 端口配置 每组配置模式都有一组特定的接口管脚&#xff0c;它们跨越7系列FPGA上的一个或多个I/O BANK。7系列器件支持3.3V、2.5V、1.8V或1.5V的I/O配置&#xff0c;包括&#xff1a; BANK 0 中的JTAG管脚、BANK0中的专用配置管脚 BANK14和BANK15中与特定配置模式相关的管…

2024 批量下载公众号文章内容/阅读数/在看数/点赞数/留言数/粉丝数导出pdf文章备份(带留言):公众号半佛仙人近1500篇历史文章在线查看,找文章方便了

关于公众号文章批量下载&#xff0c;我之前写过很多文章&#xff1a; 视频更新版&#xff1a;批量下载公众号文章内容/话题/图片/封面/音频/视频&#xff0c;导出html&#xff0c;pdf&#xff0c;excel包含阅读数/点赞数/留言数 2021陶博士2006/caoz的梦呓/刘备我祖/六神读金…

包含字母数字及特殊字符 三种组合的正则两种写法

//长度8~16位&#xff1b;包含字母、数字及特殊字符 #$%^&*_-//正则1 写法&#xff1a;let reg_1 /^(?![A-Za-z0-9]$)^(?![A-Za-z#$\%^&*_\-]$)^(?![0-9#$\%^&_*\-]$)([A-Za-z0-9#$\%^&*_\-]{8,16})$///正则2 写法&#xff1a;let reg_2 /^(?![A-Za-z#$%…

在别的地方下载的二次封装Windows镜像怎么安装?GHO镜像详细安装教程

前言 在系统之家或者其他地方下载的镜像文件怎么装到电脑上&#xff1f; 首先要知道系统之家下载的Windows镜像文件基本上都是.iso结尾的&#xff0c;要进入到对应镜像包才能看出系统镜像是什么格式。 如何分辨镜像的格式 选择对应的.iso镜像&#xff0c;点击【鼠标右键】-【装…

力扣大厂热门面试算法题 9-11

9. 回文数&#xff0c;10. 正则表达式匹配&#xff0c;11. 盛最多水的容器&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.08 可通过leetcode所有测试用例。 目录 9. 回文数 解题思路 完整代码 Java Python 10. 正则表达式…

3dmax渲染出来是黑色的怎么办?

灯光问题&#xff1a;渲染场景中的灯光可能全部关闭&#xff0c;包括默认灯光&#xff0c;或者手动添加的灯光没有开启全局光照&#xff08;GI&#xff09;。解决方法是检查并开启场景中的灯光&#xff0c;确保全局光照已开启。 摄像机问题&#xff1a;摄像机可能被黑色对象挡…

golang 注释插件

Goanno插件 自动生成golang注释,该插件为 Intellij/Goland 中的 golang 提供自动生成注释 如何使用&#xff1f; control command / (for windows: control alt /)&#xff08;生成注释&#xff09;Right click -> Generate -> Goanno&#xff08;生成注释&#x…

系统架构设计师 2023年 案例分析

一、大数据架构 Lambda架构和Kappa架构 某网作为某电视台在互联网上的大型门户入口,某一年成为某奥运会中国大陆地区的特权转播商,独家全程直播了某奥运会全部的赛事,积累了庞大稳定的用户群,这些用户在使用各类服务过程中产生了大量数据,对这些海量数据进行分析与挖掘,将…

重学SpringBoot3-WebMvcAutoConfiguration类

重学SpringBoot3-WebMvcAutoConfiguration类 是什么什么用生效条件作用 自定义配置的三种方式自定义配置举例1. 自定义 DispatcherServlet 配置2. 静态资源配置3. 自定义MVC配置4. 消息转换器5. 异常处理 是什么 org.springframework.boot.autoconfigure.web.servlet.WebMvcAut…

Linux mmap系统调用

文章目录 前言一、mmap()函数简介二、代码演示2.1 mmap使用场景2.2 私有匿名映射2.3 私有文件映射2.4 共享匿名映射2.5 共享文件映射 参考 前言 NAMEmmap, munmap - map or unmap files or devices into memorySYNOPSIS#include <sys/mman.h>void *mmap(void *addr, siz…

AcWing 505. 火柴排队(每日一题)

目录 题目链接&#xff1a;505. 火柴排队 - AcWing题库 解题思路&#xff1a; 离散化&#xff1a; 归并排序求逆序对&#xff1a; 总代码&#xff1a; 题目链接&#xff1a;505. 火柴排队 - AcWing题库 涵涵有两盒火柴&#xff0c;每盒装有 n 根火柴&#xff0c;每根火柴…

牛客小白月赛88

E.多重映射 解题思路 对集合进行整体操作&#xff0c;集合大小只增不减&#xff0c;问最后集合标号维护集合&#xff0c;考虑并查集但直接用并差集维护会有以下问题&#xff1a;当前集合变标号&#xff0c;可能会和之前标号相同&#xff0c;则进行并查集操作时&#xff0c;会接…

在Linux(Ubuntu)中使用终端编译 vscode安装

文章目录 &#x1f4da;在Linux&#xff08;Ubuntu&#xff09;中使用终端编译&#x1f407;.cpp程序编译&#x1f407;.py程序编译&#x1f407;查看Python、C编程环境 &#x1f4da;vscode安装 &#x1f4da;在Linux&#xff08;Ubuntu&#xff09;中使用终端编译 虚拟机安装…

VR全景技术在VR看房中有哪些应用,能带来哪些好处

引言&#xff1a; 随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在房地产行业中的应用也越来越广泛。其中&#xff0c;VR全景技术在VR看房中的运用尤为突出。今天&#xff0c;让我们一起深入探讨VR全景技术在VR看房中的应用及其带来的种种好处。 一、…

博特激光——激光打标机工作原理介绍

激光打标机&#xff0c;作为现代标识技术的杰出代表&#xff0c;其工作原理的高效与精确性使得它在众多行业中占据了举足轻重的地位。今天&#xff0c;我们将深入探讨激光打标机的工作原理及其背后的科技魅力。 激光打标机的工作原理主要基于激光的高能量和聚焦特性。首先&…

Python实现归并排序算法

Python实现归并排序算法 以下是 Python 中的归并排序算法实现示例&#xff1a; def merge_sort(arr):if len(arr) > 1:mid len(arr) // 2 # 计算中间索引left_half arr[:mid] # 划分左半部分right_half arr[mid:] # 划分右半部分# 递归调用对左右两半进行排序me…

SpringBoot整合Redis实现分布式锁

SpringBoot整合Redis实现分布式锁 分布式系统为什么要使用分布式锁&#xff1f; 首先&#xff0c;分布式系统是由多个独立节点组成的&#xff0c;这些节点可能运行在不同的物理或虚拟机器上&#xff0c;它们通过网络进行通信和协作。在这样的环境中&#xff0c;多个节点可能同…

前端实现单点登录

简单概括就是&#xff0c;一个系统登录&#xff0c;跳转多个系统&#xff0c;其他系统不需要再登录&#xff0c;直接进入页面 登录的系统 <template><div><div class"content"><div class"item" v-for"(item,index) in list&q…

Android使用WebView打开内嵌H5网页

Android打开外部网页链接请参考上一篇文章 https://public.blog.csdn.net/article/details/136384559 继上篇&#xff0c;新建assets文章夹&#xff0c;将H5的网页资源放到此文件夹下 把H5的资源文件都拷进来 这个时候&#xff0c;将添加打开本地网页的代码&#xff1a; //打…

【HTML】HTML基础8.1(表单标签)

目录 效果 基础知识 标签 ① ② 代码 效果 基础知识 表单的组成元素 表单控件用户所填写的信息提示信息提示用户需要填的信息表单域包含表单元素的区域 标签 ① <form action"" method""></form> <form>标签确定了一个表单域&…