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