前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >string类的函数讲解

string类的函数讲解

作者头像
ahao
发布2024-03-19 19:11:23
650
发布2024-03-19 19:11:23
举报
文章被收录于专栏:学习

标准库中的string类

首先关于string类的了解,我先给出官方的string类的讲解,以便于大家的学习:链接: http://www.cplusplus.com/reference/string/string/?kw=string 这个网站是C++官方网站,里面对于各个关键字和库函数的讲解都是很官方的,大家有需要的时候可以参考

我们对string类进行一个简单的总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  4. 不能操作多字节或者变长字符的序列。

这里有一个需要注意的点: 在使用string类时,必须包含#include头文件以及using namespace std;

下面我们就对string类的一些常用的接口进行讲解:

string类的常用接口说明
string类对象的常见构造

首先我们看看创建一个空的string类,就是一个空的字符串:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1;
	cout << s1 << endl;
	return 0;
}

输出为空:

构造string类对象:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1 << endl;
	return 0;
}

拷贝构造:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1 << endl;
	string s2(s1);
	cout << s2 << endl;
	return 0;
}

将n个字符放入一个string类中:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1(5,'a');
	cout << s1 << endl;
	return 0;
}

去一个string类中的字符存入另一个string类: 例如,将s1中第六个字符开始往后取三个字符放入s2 这里注意: 如果这里的要取字符的数量大于字符串的字符个数的话,能取多少取多少

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1 << endl;
	string s2(s1, 6, 3);
	cout << s2 << endl;
	return 0;
}
string类对象的容量操作

我们这里的size和lenth的作用是一样的,只是在后期的语言发展中为了适应需要,例如,如果是一个二叉树,用lenth合适吗,所以就引出了size 注意,这里计算出来的是有效字符个数,也就是说不包括’\0’

用法如下:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.length() << endl;
	cout << s1.size() << endl;
	return 0;
}

capacity是返回空间的大小: 至于容量为什么是15,这就是底层实现的原因了,一些编译器是基于1.5倍的扩容,比如我们的vscode,而linux的终端里是以2倍的扩容,其实不必太过于纠结这一点,我们只需要了解到这一点即可 但是各自的容量起点也不一样!

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.capacity() << endl;
	return 0;
}

empty函数的用法很简单: 例如,不为空返回0

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.capacity() << endl;
	cout << s1.empty() << endl;
	return 0;
}

clear的作用就是清空字符串: 清理之后输出空行,字符串被清空

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1 << endl;
	s1.clear();
	cout << s1 << endl;
	return 0;
}

这里有一个重点内容: reserve和resize的区别 其实二者都是用来提前开空间的,因为扩容会影响程序的效率 例如: 可以看到二者都成功地开辟了空间

并且使用resize时还可以填充多余的空间:

但其实这不是重点,重点在于: 这是resize:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.capacity() << endl;
	cout << s1.size() << endl;
	s1.resize(30);
	cout << s1.capacity() << endl;
	cout << s1.size() << endl;
	return 0;
}

这是reserve:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.capacity() << endl;
	cout << s1.size() << endl;
	s1.reserve(30);
	cout << s1.capacity() << endl;
	cout << s1.size() << endl;
	return 0;
}

大家可以发现: 用reserve来提前开辟空间,capacity改变,size不变,而用resize则是capacity和size都会发生改变!

下面给大家一个小的总结:

注意:

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  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不会改变容量大小。
string类对象的访问及遍历操作

operator[],就是返回该位置的字符,其实就是用于循环: 但是要注意一点,如果访问越界,就会直接报错,导致程序终止 并且该函数一般只适用于数组结构

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string const s1("hello world");
	for (int i = 0; i < s1.length(); i++)
	{
		cout << s1[i];
	}
	cout << endl;
	return 0;
}

迭代器: 迭代器有两种,还有一个叫做反向迭代器,就是从尾部开始遍历 在这里我们暂且把begin认为是指针来理解 我们使用正向的迭代器的时候要引出string类里面的iterator begin就默认是从零开始输出记得用解引用,指针向后移动

我们给出一张对比图:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	for (string::iterator i = s1.begin(); i != s1.end(); i++)
	{
		cout << *i;
	}
	return 0;
}

而反向迭代器就是从后开始往前移动: 这里要引出的是 reverse_iterator 其实这里的rbegin已经不在字符串的第一个位置了二者是有区别的,并且,这里的指针也是++,不然怎么会叫做反向迭代器呢?

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	for (string::reverse_iterator i = s1.rbegin(); i != s1.rend(); i++)
	{
		cout << *i;
	}
	return 0;
}

另外大家记住一个点: for循环的底层实现就是迭代器!

string类对象的修改操作

尾插字符: 尾插很简单

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	s1.push_back('!');
	cout << s1 << endl;
	return 0;
}

追加字符串: 相比较push_back,append只能追加字符串,而前者只能追加字符

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	s1.append(" hhhh!");
	cout << s1 << endl;
	return 0;
}

但是operator+=能够把上面两个函数一起实现,并且函数的可读性更高,所以我们一般选择使用+=来实现对对象的追加:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	s1+=(" hhhh!");
	cout << s1 << endl;
	s1 += ('x');
	cout << s1 << endl;
	return 0;
}

返回C字符串:

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.c_str() << endl;
	return 0;
}

返回字符串中的位置: 返回位置既可以从前往后找又可以从后往前找 find是从前往后,rfind是从后往前,npos是字符串的长度

如果找不到的话这里的npos是-1: 但是find函数返回的是无符号整形,所以-1进行了转换

截取字符: 从pos位置开始往后截取n个字符 如果n大于length-pos,能截取多少就截取多少

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	string s1("hello world");
	cout << s1.substr(3, 4) << endl;
	cout << s1.substr(3, 12) << endl;
}

下面我们对于string类的修改操作做一个小总结:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
string类非成员函数

其实这里用的不多,不做过多的讲解 但是这个getline函数是可以用到一些题目中来读取字符串的,他遇到换行符就会停止读取,遇到空格不会:

代码语言:javascript
复制
int main()
{
	std::string name;

	std::cout << "Please, enter your full name: ";
	std::getline(std::cin, name);
	std::cout << "Hello, " << name << "!\n";

	return 0;
}

好了,今天的分享到这里就结束了,谢谢大家的支持!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 标准库中的string类
    • string类的常用接口说明
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档