• 【C++】string类(详解),常见的函数都在这里,你都了解吗?


    🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
    在这里插入图片描述

    一、STL简介

    1.什么是STL?

    STL(standard template library - 标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构域算法的软件框架。
    包括vector/list/sort…标准模板库
    像istram,ostream…标准库
    标准模板库是标准库的自己

    2.STL六大组件

    在这里插入图片描述

    二、为什么会出现string类

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

    三、string类

    string类的使用需要包含头文件
    #include

    1.string类的构造函数

    在这里插入图片描述

    利用的是函数重载
    (1)无参构造
    (2)拷贝构造
    (3)部分拷贝构造,从pos位置开始拷贝构造len个位置,给的太大的话就只拷贝到str的结尾,并且第三个参数有缺省值可以不穿,注意,这里的类型是size_t,也就是无符号整数,传-1的话是很大的整数
    (4)带参构造
    (5)传一个字符串的前n个进行构造
    (6)填充,n个位置填充为char类型的c
    (7)拷贝迭代区间的内容

    注意事项:
    1.空的string类型的字符串,看似str.size()==0,但是在末尾也是放了\0的,为了符合C语言字符串的规范。
    在这里插入图片描述
    2. = 不是运算符重载,而是隐式类型转换,如果加了explicit关键字就不允许这种隐式类型转换的发生了了

    string str = "zhupi";
    /*
    	发生的隐式类型转换:
    	1.“zhupi”进行传参的构造函数(4)
    	2.str与构造好的函数进行拷贝构造(2)
    	编译器发生了优化,这个过程优化为一步完成
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    其次,需要区分赋值运算符重载和隐式类型转换,赋值运算符重载是用于已经定义好了,用于重新赋值

    //隐式类型转换
    string s1 = "zhupi"
    //赋值运算符重载
    string s2 = "zhupi";
    s2 = "xiongdi";
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.string的operator[]和at

    at和operator[]的功能是类似的,但是operator[]越界是报错,at越界是抛异常。
    在这里插入图片描述
    在这里插入图片描述
    operator[]像数组一样去访问,会检查越界,越界了就直接奔溃

    string str="zhxpi";
    str[2] = 'u';
    cout<< str<<endl;//zhupi
    
    • 1
    • 2
    • 3

    3.string的Capacity容量相关

    在这里插入图片描述

    1.size和length都是求string的长度,但是推荐用size(),因为和后面一致,比如说树,树用length就不合适了
    2.max_size()就是最大长度,没什么用
    3.capacity就是容量的大小,不同的编译器扩容机制是不同的
    4.reserve,就是把空间提前开好,比如需要1000个空间 reserve(1000);因为扩容是有消耗的,所以提前开好,避免扩容,减少消耗,提高效率
    5.resize是开空间+初始化 resize(1000,‘x’);不给初始化值得话默认就是\0,和resize相比,reserve是单纯得开空间。
    6.clear就是清掉所有数据
    7.empty就是判空

    4.迭代器

    迭代器iterator是一个像指针一样得东西,有可能是指针,也有可能不是指针,但是用法像指针

    四种迭代器

    共有四种迭代器,正常迭代器,反向迭代器,const_正向迭代器,const_反向迭代器

    在string类中的写法:
    string::iterator
    string::const_iterator
    string::reverse_iterator
    string::const_reverse_iterator

    迭代器的重要性

    迭代器属于STL框架设计的六大组件之一,但是string不喜欢用迭代器iterator,[]更好用,但是vector,list…都能用,vector也喜欢用[],但是list必须使用迭代器,包括以后学的map,set等等,iterator迭代器才是所有容器通用的访问方式,用法类似。迭代器才是万能的

    5.三种遍历方式

    正常方式

    string str ="zhupi";
    for(int i=0;i<str.size();i++)
    {
    	cout<< str[i]<<" ";
    }
    cout<<endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    利用迭代器

    string str = "zhupi";
    string::iterator it = str.begin();
    while(it!=str.end())
    //str.end()返回的是最后一个位置的下一个,也就是\0的位置
    {
    	cout<< *it<<" ";	
    	it++;
    }
    cout<<end;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    范围for

    范围for的底层还是用的迭代器,并且每次访问后自动it++;

    string str = "zhupi";
    for(auto ch : str)
    //如果想修改for(auto&ch : str)
    {
    	cout<<ch<<" ";
    }
    cout<<endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6.rbegin,rend反向迭代器

    string str = "zhupi";
    string::iterator rit = str.rbegin();
    while(it!=str.rend())
    {
    	cout<<*rit<<" ";
    	rit++;//注意方向是反的,是++而不是--;
    }
    cout<<endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    其实,string::iteratir rit = str.rbegin()
    也可以写作 auto it = str.rbegin();初学的时候还是好好写

    7、string中常用的+=

    首先,介绍两个函数 push_back和append

    push_back

    添加一个字符

    string str = "zhu";
    str.push_kack('p');
    str.push_back('i');
    cout<<str;//zhupi
    
    • 1
    • 2
    • 3
    • 4

    append

    添加字符串

    string str = "zhu"
    str.append("pi");
    cout<<str;//zhupi
    
    • 1
    • 2
    • 3

    +=

    最好用的是重载了一个+=,底层就是用的push_back()和append()

    string str ="zh";
    str+="up";
    str+="i";
    cout<<str;//zhupi
    
    • 1
    • 2
    • 3
    • 4

    strcat的缺点与+=的优点

    strcat的缺点:
    1.需要用的空间需要自己准备
    2.每次都要先遍历一个找到尾才开始追加,效率低

    +=的优点
    1.因为有索引,所以直接找到尾
    2.底层实现空间不够自己扩容,底层去带哦用push_back和append

    8.insert与erase

    在某个数据前面插入字符字符串,通常配合find使用
    对于插入来说,不能我们手动去挪动数据,因为空间可能没有开好
    那么对于把空格换成%20来说,可以先insert再erase掉空格

    void test()
    {
    	string str = "wo lei le";
    	for (size_t i=0;i<str.size();i++)
    	{
    		if (str[i] == ' ')
    		{
    			str.insert(i, "%20");
    			i += 3;
    			if (i < str.size())
    				str.erase(i, 1);//从i位置开始n个
    		}
    	}
    	cout << str;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    9.c_str

    C语言是不支持string的,所以c_str返回的是char*,为了符合C语言的形式,比如

    string filename("test.cpp");
    //C语言的文件操作
    fopen(filename,"r");//报错,因为c不支持string
    
    
    • 1
    • 2
    • 3
    • 4

    c_str是以\0为准的
    string是以size()为准的

    同时,发现VS监视窗口下的一个小bug,监视窗口不能够显示\0以后的值
    在这里插入图片描述

    10.find

    在这里插入图片描述

    从头开始去找第一个符合目标的位置
    size_t pos = filename.find(‘.’);
    找到了返回的是pos,没有找到返回npos
    string::npos其实是size_t无符号整型的最大值

    在这里插入图片描述

    11.substr

    在这里插入图片描述
    返回从pos位置开始,长度为len的子串

    string str = "zhupi";
    size_t pos = str.find('z');
    string subStr = str.substr(pos,3);
    cout<<subStr<<endl;//zhu
    
    • 1
    • 2
    • 3
    • 4

    12.rfind

    和find类似,只不过是倒着找

    string str = "zhupizxx";
    size_t pos = str.rfind('z');
    string subStr = str.substr(pos,3);
    cout<<subStr<<endl;//zxx
    
    • 1
    • 2
    • 3
    • 4

    13.find_first_of

    find与find_first_of的区别
    1.find是找目标字符或者字符串的位置,字符串一定要相等
    2.find_first_of是找与字符串当中某个字符相等的字符位置

    在这里插入图片描述

    string str = "zhupi";
    size_t pos = str.find_first_of("abcdu");
    cout<<str[pos]<<endl;//u
    
    • 1
    • 2
    • 3

    14.可接受空格的getline

    cin>>str和scanf(“%s”,str);都不会接受空格
    对于这两种而言,可接受空格的办法:
    1.scanf(“%[^某个符号]”,str);//遇到什么符号才停止
    2.getline(istream&in,str);
    在这里插入图片描述

    15.相关的转换函数

    stoi string转换为int
    stol string转换为long
    stof string 转换为float
    stod string转换为double
    还有其他的可以自己查一查文档

    四、string类总结

    在C++中,string类提供很多內建方法,可以无害地进行增删改查,基本覆盖用户的所有操作,用户并不需要了解底层实现,拿来直接用,也不会造成内存的问题,对初、中级水平程序员非常友好,而且还有一些亮点,还是很重要的!
    在这里插入图片描述

  • 相关阅读:
    Leetcode -1
    Bean实例化的基本流程
    【笔者感悟】笔者的工作感悟【五】
    C语言每日一题(26)移除链表元素
    Docker自定义镜像-Dockerfile
    Java注解
    Vue3 源码阅读(9):渲染器 —— diff 算法
    python将图片转为位图转为十六进制ASCII字符
    (故障集)——新安装的Ubuntu系统重启后ens33没了
    《精通Neo4j》前言
  • 原文地址:https://blog.csdn.net/zhu_pi_xx/article/details/126664196