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库中有这个东西,到时候直接查看使用即可。

目录
相关文章
|
23天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
29 1
|
1月前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
51 7
|
2月前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
102 4
|
1月前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
47 0
|
13天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
54 18
|
13天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
38 13
|
13天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
37 5
|
13天前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
28 5
|
13天前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
33 4
|
13天前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
26 3