【C++】string类接口的了解和使用
创始人
2024-02-17 12:40:25

为什么我们要学string类呢?那是必须是为了方便啊!在C语言中,我们创建一个字符串,有很多操作或者必须要注意的细节会把控不住,所以C++中出现了string类,让我们应对字符串等oj题也方便快捷了许多!


目录

一、STL的介绍

二、标准库中的string类

1、简介string​编辑

2、库中的string类的常用接口说明​编辑

 1.构造函数

           2.npos 

           3.遍历 

3.capacity

 1.size,lenth,max_size,capacity

 2.shrink_to_fit

 3.reserve、resize(重点)

4.operator[],at

5、Modifiers

1.push_back, append, operator+=

         2.insert,erase

         3.assign,replace(不重要)

         4.find,c_str,substr

总结 


一、STL的介绍

STL(standard template libaray-标准模板库):C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架STL的六大组件 :仿函数、算法、迭代器、空间配置器、容器、配接器。 这些在我们接下来的学习都会深入学习! 网上有句话说:“不懂STL,不要说你会C++”。STL是C++中的优秀作品,有了它的陪伴,许多底层的数据结构 以及算法都不需要自己重新造轮子,站在前人的肩膀上,健步如飞的快速开发。

二、标准库中的string类

1、简介string

 string是一个模板,是因为编码不同,导致char的字节数不同,所以需要模板来适应不同的编码类型,原型差不多就是这样的:

 我们接下来研究的:utf-8,char为一个字节的string类

 

 2、库中的string类的常用接口说明

   1.构造函数

在学习任何类之前,当然要先看它的构造函数了!(我们只了解重要且常用的)

 构造函数:直接上例子:

  可以看得出,s1为默认的构造函数

s2是带参的构造函数(理解:会开辟一段空间,将内容存起来)

s3的构造方式,会发生隐式类型转换,会产生临时变量,先构造,再拷贝构造,优化后就是构造

s4构造是用n个char c 字符去初始化

拷贝构造:自定义类型拷贝会发生深拷贝,所以形参一般要用引用减少拷贝,提高效率

s5,s6都是拷贝构造


2.npos

npos是一个静态成员变量,无符号整型,是一个极大的数。

对于这个构造函数,是在str的pos位置开始向后len的长度,这段字符串进行初始化。

那默认不传len,len的值就是npos,是一个非常大的数,当len大于str的长度时,默认到了str的最后一位。

3.遍历 

共有三种遍历方式:

void test2()
{string s1("12345678");// 1、下标 []for (size_t i = 0; i < s1.size(); ++i){s1[i]++;}cout << s1 << endl;// 2、范围forfor (auto& ch : s1){ch--;}cout << s1 << endl;// 3、迭代器  -- 通用的访问形式string::iterator it1 = s1.begin();while (it1 != s1.end()){*it1 += 1;++it1;    // 把string里的内容每一个都加了一}it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";   //打印每一个内容++it1;}cout << endl;
}

可以看的出:operator[]有两个接口,一个是有const,一个没有const

operator[],是一个可读且可写的接口。

当const只读对象调用时,就会调用const接口

当只写对象调用时,就会调用非const,

所以对于即可写又可读的接口函数来说,就有两个版本,const和非const

  

还有一点:operator[]内部有防止越界访问的功能:assert(pos<=size);

迭代器的遍历方法:

这里的迭代器是string类的自定义的一种类型,需要string::

迭代器我们现在可以看作是 和指针相差不多的东西(行为像指针),但他又不是指针,具体的底层我们后面会见面。

begin()就是指向第一个位置,end()指向最后一个有效字符的下一个位置

迭代器要注意的地方:

我们可以看到:迭代器也分为const和非const,那什么时候分别用哪个呢?

const_iterator:只能在const对象下使用,并且const迭代器可以改变迭代器本身,但不能改变迭代器所指向的内容 

迭代器有正向迭代器和反向迭代器:

void Print(const string& s)
{// 只读不写,可以遍历改变it,但不能改变他指向内容string::const_iterator it = s.begin(); //正向迭代器while (it != s.end()){// *it += 1;  错误!cout << *it << " ";++it;//正向迭代器就是正着迭代++}}cout << endl;//string::const_reverse_iterator rit = s.rbegin();auto rit = s.rbegin();       //反向迭代器while (rit != s.rend()){cout << *rit << " ";++rit;//都是++,这里不可以类比指针反向迭代器就是反着迭代++}cout << endl;
}

学会了吗?


 3.capacity

1.size,lenth,max_size,capacity

在string中,我们会怎么描述字符串长度??length是不是更贴合,那为什么又有size呢??

因为string是早于stl的,在它之后size更普遍适用,为了普遍化,那只能添加一个size了

size==length,就是求长度或者字符个数。(length淘汰!!)

只读接口,加const

 capacity:string的容量,和size可不相同。

clear:因为stl只是规范了每个接口名字或者参数,但并没有将每一个容器函数的细节拿捏死,所以对于clear,我们并不知道他清空数据以后,是否还要回收空间。得需要验证!

void test4()
{string s("hello world");cout << s.size() << endl;cout << s.length() << endl;cout << s.capacity() << endl;s.clear();cout << s << endl;cout << s.capacity() << endl;
}

可以发现,clear之后并没有回收空间,也不会缩容

empty(),就是来判空的


2.shrink_to_fit

当capacity大于size时,将size和capacity保持一致,会缩容,但缩容代价还是挺大的,一般也不这么搞。


3.reserve、resize(重点)

  只改变capacity

在我们知道需要多少空间时,插入数据,为了防止反复扩容(扩容代价大),我们可以提前预留空间,开辟好。

那到底是怎么扩的呢??一次扩多少?

我们在vs和g++上分别测试得出:vs上面会1.5倍扩容,但是存在内存对齐问题,会有些许偏差,但空间还是大于我们要开辟的。g++就是2倍扩容,要多少扩多少,不会有偏差。

 第一次预留500,第一次扩容到766,第二次扩容1149,差不多就是1.5倍

resize:它改变的是 size

当n不同,resize会分为三种情况:(n为size改变后的值)

举例说明:

void test6()
{//当ncapacity,  (扩容+插入数据)string s3("hello world");s3.resize(20, '#');cout << s3.size() << endl;cout << s3.capacity() << endl;cout << s3 << endl << endl;
}

所以resize功能还是比较完善健全的。

 4.operator[],at

 他们是一样的,都是读写到string中的某个值,进行操作。

但是区别在于:当发生越界时,operator[]会直接assert()报警告;而at则会抛异常(后面我们会详细了解)

5、Modifiers

1.push_back, append, operator+=

插入:

push_back :尾插

下面通过举例来观察: 

void test7()
{//push_backstring s1("hello world");s1.push_back('x');s1.push_back('y');cout << s1 << endl;//appendstring s2("1111111111");s2.append(s1);cout << s2 << endl;//operator+=string s3("666");s3 += ' ';s3 += "hello world";s3 += s2;cout << s3 << endl;
}

 

2.insert,erase

适用于头插,头删,中间插入和删除

但这两种函数我们都不建议经常使用,因为它的效率很低,在删除或者插入时,就会有数据挪动,效率很低。

void test8()
{string s("hello world");s.insert(0, "bit");cout << s << endl;s.erase(0, 3);cout << s << endl;s.insert(5, "bit");cout << s << endl;s.erase(5,3);cout << s << endl;s.erase(5);  //第二个参数不提供,默认是npos,直接从pos删到最后一个。cout << s << endl;
}

 3.assign,replace(不重要)

assign(功能):先clear,再赋值 

replace:替换内容

void test9()
{string s("3456789");s.assign("1234");cout << s << endl;string s1("hello world");s1.replace(6, 10, "666");cout << s1;
}

4.find,c_str,substr

find:也有缺省值,默认不提供,直接找到最后一个

c_str:取出C形式字符串(底层指针)

  

substr:取出str的一部分,再将其构建成新对象返回

  

getline:输入可以中间带空格的字符串


总结

这就是我们经常要用到的函数接口,更底层的内容,需要我们在模拟实现的时候,去好好感悟,下期再见!

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...