当前位置: 首页 > news >正文

C++STL详解(一)——string类的接口详解(下)

目录

一.string的大小和容量成员函数

1.1size()和length()

1.2capacity()

1.3resize()

 1.4reserve()

1.5clear()和empty()

​编辑 二.string元素的访问

2.1operator[]和at()

2.2范围for

三.string中迭代器相关函数

3.1begin()和end()

3.2rbegin()和rend()

四.string与字符串之间的转换

五.string中子串的提取

5.1substr()

5.2通过copy()提取子串。

六.string中的运算符重载

6.1operator+操作符

6.2输入输出操作符

七.string中getline函数

 八.后记


一.string的大小和容量成员函数

1.1size()和length()

在C语言中,我们可以通过下式来计算字符数组中有多少个元素

	sizeof(arr[0]) / sizeof(arr);

在string库中,有如下两个接口可以计算元素个数:

	size();length();

如下图所示:

虽然这两个函数都可以完成对元素个数的计算,但我们更推荐使用size()函数计算元素的个数。

这是因为在STL中,都重载了size()这个函数,却没有重载length()函数。

1.2capacity()

capacity()函数用来获取字符串开的空间。

size_t capacity() const;

在这里需要大家注意的是,capacity表示开辟的空间大小,而size求出的是开辟的空间内的元素个数。因此这两个数是可以不相等的。

 如下图:

我们发现,我们开了15个空间存储这个字符串,但是只用了其中的七个空间。 

1.3resize()

resize是改变当前字符串有效字符个数的函数。 

void resize (size_t n);
void resize (size_t n, char c);

resize规则:

  • 当n大于对象当前的size时,将size扩大到n,扩大的字符为c,若c未给出,则默认为’\0’。
  • 当n小于对象当前的size时,将size缩小到n。 

我们可以通过下图的代码来验证上述规则: 

另外,值得一提的是,如果resize给出的值大于capacity的值的话,会调用扩容函数。

 1.4reserve()

reserve()是操作设置capacity的函数。函数原型如下:

void reserve (size_t n = 0);

 reserve规则:

  • 当n大于对象当前的capacity时,将capacity扩大到n或大于n。
  • 当n小于对象当前的capacity时,将capacity缩小或什么也不做。

我们可以通过下图来验证上图的规则:

这里需要我们大家注意两点内容

  1. reserer()函数并不会影响到字符串内的字符数据。
  2. reserve()在一些编译器中也可能会缩容。 

1.5clear()和empty()

clear()函数用来清空字符串内的字符数据。 

void clear();

clear规则:

  • 字符数据清除掉,使其成为空字符串
  • size设置为0 

实例如下: 

 empty函数进行判空,即判断字符串是否为空字符串。

bool empty() const;

如果字符串为空的话,则返回真。

如果字符串不为空的话,则返回假。

 
二.string元素的访问

2.1operator[]和at()

string元素的访问有两种方式,我们可以通过重载的[]访问,也可以通过at函数访问。

   char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;char& at (size_t pos);
const char& at (size_t pos) const;

由于两者都是传引用返回,因此两者都可以修改数据。

我们先使用operator[]来进行实践: 

现在我们通过at来进行实践:

  

2.2范围for

同样的,我们也可以通过范围for来访问和修改字符串内的数据。

我们可以使用下图中的方式来访问数据:

但是,在使用范围for修改数据时,则需要我们传引用了,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。

因此,使用范围for修改数据的正确方法如下:

		for (auto& e : str){e = 'x';}

三.string中迭代器相关函数

3.1begin()和end()

begin函数:返回一个指向字符串第一个字符的迭代器。

end函数:返回一个指向字符串结束字符的迭代器,即’\0’。

函数原型如下:

    iterator begin();const_iterator begin() const;iterator end();const_iterator end() const;

 我们同样可以通过迭代器来访问和修改数据,如下所示: 

string str("xiaoqiulaoshi");
string::iterator it1 = str.begin();
while (it1 != str.end())
{cout << *it1 << ' ';it1++;
}
cout << endl;//x i a o q i u l a o s h i
string::iterator it2 = str.begin();
while (it2 != str.end())
{*it2='x';it2++;
}
cout << str << endl;//xxxxxxxxxx

3.2rbegin()和rend()

在string库中,还提供了反向迭代器rbegin和rend。

rbegin函数:返回指向字符串最后一个字符的反向迭代器。

rend函数:返回指向字符串第一个字符前面的理论元素的反向迭代器。

函数原型如下:

    iterator rbegin();const_iterator rbegin() const;iterator rend();const_iterator rend() const;

为了方便大家理解,我们来画图表示rbegin和rend的指向。


四.string与字符串之间的转换

在学习过数据结构之后,我们知道实现一个string类,私有成员需要有char* 、size、capacity。

如果我们只需要char*的话,则可以通过c_str()函数来进行转换。

我们将c_str()转换过来的字符串称为C字符串/C风格字符串。也就是我们上文中说的字符序列。

函数原型如下: 

const char* c_str() const;

使用方法如下:

const char* str2 = s.c_str();


五.string中子串的提取

我们有两种方法提取子串,分别是通过substr提取以及通过copy出一个字符串的部分字符到另外一个字符串中。

5.1substr()

函数原型如下:

string substr (size_t pos = 0, size_t len = npos) const;

我们可以通过下面的代码提取子串: 

int main()
{	string s1("abcdef");string s2;//substr(pos, n)提取pos位置开始的n个字符序列作为返回值s2 = s1.substr(2, 4);cout << s2 << endl; //cdefreturn 0;
}

5.2通过copy()提取子串。

 函数原型如下:

size_t copy (char* s, size_t len, size_t pos = 0) const;

 我们可以通过如下方法来提取子串:

int main()
{string s("abcdef");char str[20];//copy(str, n, pos)复制pos位置开始的n个字符到str字符串size_t length = s.copy(str, 4, 2);//copy函数不会在复制内容的末尾附加'\0',需要手动加str[length] = '\0';cout << str << endl; //dcefreturn 0;
}


六.string中的运算符重载

我们在前面的内容中已经介绍了很多操作符,现在我们再介绍几个操作符。

6.1operator+操作符

operator+操作符和operator+=操作符的作用是类似的。

重载后的+操作符支持如下操作:

 string类 + string类
 string类 + 字符串
 字符串 + string类
 string类 + 字符
 字符 + string类

譬如如下代码: 

int main() {// 定义字符串和字符string str1 = "Hello";string str2 = "World";const char* cstr = " C++";char ch = '!';// 1. string类 + string类string result1 = str1 + str2;cout << "string + string: " << result1 << endl; // 输出 "HelloWorld"// 2. string类 + 字符串 (C风格字符串)string result2 = str1 + cstr;cout << "string + C-style string: " << result2 << endl; // 输出 "Hello C++"// 3. 字符串 + string类string result3 = cstr + str2; // C风格字符串 + string类cout << "C-style string + string: " << result3 << endl; // 输出 " C++World"// 4. string类 + 字符string result4 = str1 + ch;cout << "string + char: " << result4 << endl; // 输出 "Hello!"// 5. 字符 + string类string result5 = ch + str1; // char + string类cout << "char + string: " << result5 << endl; // 输出 "!Hello"return 0;
}

6.2输入输出操作符

我们的string中也重载了输入输出操作符。

	void test15(){string s;cin >> s;//输入cout << s<< endl;//输出}

我们可以通过这个操作来输入和输出函数。

但是,我们发现了一个问题,如果我们输入的字符串中有空格的话 则空格后的字符会进入缓冲区。

因此,我们便可以用到getline函数。


七.string中getline函数

在用>>进行输入操作时,当>>读取到空格便会停止读取,基于此,我们将不能用>>将一串含有空格的字符串读入到string对象中。

这时,我们就需要用getline函数完成一串含有空格的字符串的读取操作了。

getline()函数的原型如下:

istream& getline (istream& is, string& str);

getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止。

int main()
{string s;getline(cin, s); //输入:hello kcout << s << endl; //输出:hello kreturn 0;
}

 同样的,getline也可以自定义分隔符delim终止。

这个版本的getline原型如下:

istream& getline (istream& is, string& str, char delim);

这个函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\n’为止。 

int main()
{string s;getline(cin, s, 'D'); //输入:hello CSDNcout << s << endl; //输出:hello CSreturn 0;
}

 八.后记

string类的接口上是这篇博文:string接口上

有关string类的模拟实现可参考此片博文:string的模拟实现

如果你想更深入的了解string类函数的使用方法,可参考cpp官网:cpp官网

码字不易,给个点赞收藏叭~~~

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 北醒单点激光雷达更改id和波特率以及Ubuntu20.04下CAN驱动
  • SQL中的函数
  • [k8s源码]7.indexer
  • 设计模式13-单件模式
  • OS Copilot初体验的感受与心得
  • Boost搜索引擎:如何建立 用户搜索内容 与 网页文件内容 之间的关系
  • 某某物联rabbitmqhttp二轮充电桩协议充电协议对接
  • 【.NET】asp.net core 程序重启容器后redis无法连接,连接超时
  • mariadb安装centos再次踩坑
  • 数学建模学习(1)遗传算法
  • 数据库结构之b树
  • canvas:矢量点转栅格
  • Google Cloud Platform数据工程简介
  • 网页隐藏版之一行小说阅读器
  • Pycharm软件Win 64位安装包+详细安装步骤 百度云
  • Git学习与使用心得(1)—— 初始化
  • input的行数自动增减
  • Java超时控制的实现
  • Laravel Telescope:优雅的应用调试工具
  • Laravel 中的一个后期静态绑定
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • PAT A1050
  • Puppeteer:浏览器控制器
  • select2 取值 遍历 设置默认值
  • vue中实现单选
  • Windows Containers 大冒险: 容器网络
  • windows下mongoDB的环境配置
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 关于字符编码你应该知道的事情
  • 解析带emoji和链接的聊天系统消息
  • 入门到放弃node系列之Hello Word篇
  • No resource identifier found for attribute,RxJava之zip操作符
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 回归生活:清理微信公众号
  • ​Linux·i2c驱动架构​
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ###STL(标准模板库)
  • #define,static,const,三种常量的区别
  • (3)STL算法之搜索
  • (function(){})()的分步解析
  • (编译到47%失败)to be deleted
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (算法)前K大的和
  • (学习日记)2024.01.19
  • (转)视频码率,帧率和分辨率的联系与区别
  • . NET自动找可写目录
  • .Mobi域名介绍
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .Net Remoting(分离服务程序实现) - Part.3
  • .net 调用php,php 调用.net com组件 --
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
  • .net开发时的诡异问题,button的onclick事件无效
  • /proc/interrupts 和 /proc/stat 查看中断的情况
  • :中兴通讯为何成功