C++入门第六篇---STL模板---string【上】string模板的介绍(下)

简介: C++入门第六篇---STL模板---string【上】string模板的介绍(下)
3.empty函数:

返回字符串是否为空,是则为true,反之返回false.

4.clear函数:

清空字符串,它的实现原理其实就是在下标为0的位置放一个\0,由于要迁就C语言的关系,C++也同样识别到\0停止,所以我们下标为0的位置放入\0,就相当于字符串被清空了(但同时也别忘了改变_size=0),不过注意capacity一般是不轻易改变的,但size是实时改变的

5.reserve函数:

注意reserve调整的是capacity而不是size,别看混了

6.resize函数:

改变的是size,而不是capacity,同时,我们这里不仅可以调整size,对于多开的位置,我们可以指定字符char c放入。

7.shrink_to_fit函数:

缩容空间的作用,不过多赘述,它可以缩容capacity让其和对应的size匹配到一起

细节问题:

容量操作类的细节理解:

1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小,也就是说不改变capacity的大小
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 res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

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

1.operator[]string下标访问赋值重载函数:

通过这个函数,我们就可以向访问数组下标一样访问字符串的元素内容。

学会了这个函数之后,我们就可以这样遍历字符串:

string d1("hbw66");
int i=0;
for(i=0;i<d1.size();i++)
{
      cout<<d1[i]<<" ";
}
2.begin end函数:(cbegin cend就是const 版本的begin end)

看到上面的图片,我们会很疑惑它这里的iterator是什么呢?其实,这里的iterator便是迭代器类型的变量的意思,而在这里,begin会返回指向第一个元素位置的迭代器变量,而end会返回最后一个元素的下一个元素位置的迭代器变量,即\0的位置。

所以下面让我们先介绍一下迭代器:

补充迭代器的知识点!!!!:

迭代器关键字iterator,迭代器类型的本质实际上是一种指针,但它是string里面的一个内部类,要通过string域限定符去访问,即string::iterator it,迭代器适用于各种容器模板的场景,这一点是要比我们上面的单纯遍历更加的适用。由于迭代器就跟指针一样,故迭代器也需要解引用才能访问或者修改里面的具体元素。

迭代器完全体现了面向对象的封装,根据不同的适用情况去适配不同的迭代器,常见的string迭代器在这里有四种:

1.const_iterator:const的string类迭代器
2.const_reverse_iterator:const类的翻转string迭代器
3.reverse_iterator:非cosnt类的翻转迭代器
4.iterato:正常迭代器

由于迭代器前面的限制需要注意的太多,我们可以用auto自动识别类型同时简化代码,这样不会误判类型,让auto自动去匹配对应的类型。

由此,我们就可以这样遍历字符串了:

string d1("hello world");
auto it=d1.begin();
while(it!=d1.end())
{
    cout<<*it<<" ";
    it++;
}

通过对迭代器的解引用和操作,从而实现遍历的效果,还记得我们之前说过的范围for么?本质上,范围for可以实现++,向后走的功能就是通过迭代器,故范围for本质上就是通过迭代器来实现的,范围for在调用代码时,其实本质上调用的就是迭代器遍历,这一点是可以检验的,在后面我们模拟实现string模板的时候我会再提及。

3.rbegin rend函数 (crbegin crend):

相当于反向遍历字符串,其他的使用方式和begin end相同,本质上也是返回迭代器。

4.at函数:

这里的at函数作用和[]运算符重载一样,但唯一的不同是,at发生越界时会抛异常,故我们需要try catch接收,而[]则是直接报错终止掉程序,相当于assert断言的效果

4.字符串操作修改类:

1.push_back函数:

在字符串中尾插一个字符,注意根据函数,它只能尾插字符不能尾插字符串

2.append函数:

在字符串中尾插一个字符串,根据函数参数的书写,我们可以插一整个字符串,也可以根据需要只尾插一部分或者指定长度的字符串的一部分,也可以插一个string类

3.operator+=运算符重载函数(尾插最常用的一个!!!):

功能相当于push_back和append的合体,更加简便和适用,所以为什么说STL模板很复杂冗余呢?明明有+=这样好的,再写一个push_back和append意义不大。

4.operator+函数:

这里不过多赘述,就是对原字符加上字符从而创建一个新的字符串,但同时原字符不发生改变。

5.assign函数:

把assign里面的一部分赋值给接收值,但接收值之前的数据会被覆盖,可以控制长度

6.insert函数:

在指定位置的前面插入,可以插一个字符,也可以插一个字符串,或者一个string类,同时还可以指定个数的插入

7.erase函数:

在指定位置删除,可以指定长度,或者指定迭代器,或者指定删除的范围

8.replace函数:

可以在指定位置替换插入字符或者字符串的函数,它可以指定替换单个字符,也可以在单个字符的位置直接替换插入一整个字符串:

如下:

string d1("hello world");
d1=d1.replace(3,"hbw040115");
cout<<d1<<endl;

这样,打印出来的结果就是helhbwo4o115 world。

但由于涉及到挪动数据的问题,erase insert replace这三种函数都是不提倡使用的,因为太影响效率了

9.c_str函数:

以C语言的方式返回字符串,也就是说结尾是带\0的,这是C++兼容C语言的体现。

10.swap函数:

用来交换两个字符串的this和str的函数,本质上就是交换这两个字符串的地址赋给对应的指针,让this的指针指向str的位置,str的指针指向this的位置

swap中还封装了一个全局函数swap,即this不是隐藏的而是正正好好写出来的两个string参数,这个时候一旦调用可能会涉及到深拷贝的问题,故通过这个全局函数swap,让用户无论怎样调用都是这个类里面的函数,提高了效率

5.find查找系列:

1.find函数(rfind就是倒着找的函数,用法和find没事区别,但是从末尾开始):

找到指定的符号在字符串中的对应位置,并且返回这个位置对应的下标,如果找不到,就返回npos即极大长度值

2.substr函数:

将指定下标之间的元素返回给一个string类,这个函数一般配合find使用,可以起到分割字符串的作用如下:

hbw::string d2("http://www.google.com/feference/peffect/friend/");
  hbw::string sub1, sub2, sub3;
  size_t i1 = d2.find(':');
  if (i1 ==d2.getnpos())
  {
    cout << "没有找到i1" << endl;
  }
  else
  {
    sub1 = d2.substr(0, i1);
  }
  size_t i2=d2.find('/',i1+3);
  if (i2 == d2.getnpos())
  {
    cout << "没有找到i2" << endl;
  }
  else
  {
    sub2 = d2.substr(i1 + 3,i2-(i1+3));
  }
  sub3 = d2.substr(i2 + 1, d2.size() - (i2 + 1));
  cout << sub1 << endl;
  cout << sub2 << endl;
  cout << sub3 << endl;

在这里,它可以将网址分隔开三个部分。

3.find_first_of /find_last_of/find _first_not_of/find_last_not_of函数:

fing_first_of用来从头找字符串中是否有指定的字符,并返回下标,而last则到着找,而带not的则是反过来,找字符串中不是指定字符的字符并返回其下标,last同理也是倒着找.

6.其他重要函数类:

1.getline函数:

getline是可以重新设置字符串的结束标志的函数,它默认会直接识别读取到一行结束,无视空格,一旦用户指定符号,就一直读到指定符号后结束,这个很关键,在oj题里使用C++很常用

2.operator>> /opeerator<<流插入流提取的运算符重载:

不多赘述,模拟实现时我们详解,在这里我们先知道,它可以让string类型也使用<< >>符号输入输出字符串,十分方便

3.relational operators比较大小运算符重载函数:

用来比较两个字符串大小的函数,其实现大致利用了strcmp函数,对于这一系列运算符重载函数,可以让我们对于string类也可以使用内置类型的操作符,更加方便。

只需要注意其实现的时候,运算符重载多用复用实现即可,这个后续在模拟实现的时候我会演示。

总结:

以上便是我们string模板的介绍和一些函数用法的解析,下一篇文章中我们将进一步模拟实现这些函数,从而让我们进一步理解他们的用法,想要熟练使用STL库,我们需要多多刷题反复使用这些函数,自然而然就记住了,对于一些不常见的我们直接查文档,记不住也不要焦虑,那意味着并不常用,我们只需要明确STLstring库中有这个东西,到时候直接查看使用即可。

目录
相关文章
|
19小时前
|
C++
C++类和类模板——入门
C++类和类模板——入门
7 1
|
22小时前
|
C语言 C++
C++对C的改进和拓展\string类型
C++对C的改进和拓展\string类型
|
2天前
|
存储 C++ 容器
C++一分钟之-变量与数据类型入门
【6月更文挑战第18天】**C++编程基础:变量与数据类型概览** 了解变量(存储数据的容器)和数据类型是编程入门的关键。声明变量如`int age = 25;`,注意初始化和类型匹配。基本数据类型包括整型(int等)、浮点型(float、double)、字符型(char)和布尔型(bool)。理解类型范围和精度,使用字面量后缀增强可读性。深入学习数组、指针、结构体和类,以及动态内存管理,避免数组越界和内存泄漏。不断实践以巩固理论知识。
13 1
|
3天前
|
算法 前端开发 Linux
【常用技巧】C++ STL容器操作:6种常用场景算法
STL在Linux C++中使用的非常普遍,掌握并合适的使用各种容器至关重要!
31 10
|
5天前
|
存储 算法 程序员
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
15 4
|
5天前
|
存储 缓存 编译器
【C++进阶】深入STL之list:模拟实现深入理解List与迭代器
【C++进阶】深入STL之list:模拟实现深入理解List与迭代器
8 0
|
5天前
|
C++ 容器
【C++进阶】深入STL之list:高效双向链表的使用技巧
【C++进阶】深入STL之list:高效双向链表的使用技巧
9 0
|
5天前
|
编译器 C++ 容器
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
11 0
|
5天前
|
存储 算法 程序员
【C++进阶】深入STL之vector:构建高效C++程序的基石
【C++进阶】深入STL之vector:构建高效C++程序的基石
13 1
|
5天前
|
编译器 C++
【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
12 1