前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】标准库类型string

【C++】标准库类型string

作者头像
修修修也
发布2024-04-01 16:34:46
1130
发布2024-04-01 16:34:46
举报

string类简介

在实际开发中会经常使用字符串,所谓的字符串就是指一连串的字符,它由许多单个字符连接而成。字符串中可以包含任意任意字符,这些字符必须包含在一对英文双引号( " " )之内,例如"abc"。C++中定义了String类来封装字符串,并提供了一系列操作字符串的方法,它们都位于<string>头文件中。

我们先来看一下https://legacy.cplusplus.com/网站对string类的文档介绍:string类文档

总结如下:

string是表示字符串的字符串类

该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

string在底层实际是:basic_string模板类的别名,即:

代码语言:javascript
复制
typedef basic_string<char, char_traits, allocator>string;

不能操作多字节或者变长字符的序列。

在使用string类时,必须包含#include头文件以及using namespace std;


string类常用接口(成员函数)

📌string类对象默认成员函数

🎏string类对象构造函数

如下,C++98标准中对于string类实现了7个重载的构造函数:string类查询文档

其参数解析如下:

接下来我们演示使用如下四种常见的string类构造函数: 函数名称功能说明string()构造空的string类对象,即空字符串string(const char* s)用C-string来构造string类对象string(size_t n,char c)string类对象中包含n个字符cstring(const string&s)拷贝构造函数

如下代码,分别按上述构造函数顺序调用了相应构造函数初始化了4个string类对象:

代码语言:javascript
复制
#include<iostream>
#include<string>

using namespace std;

int main()
{
	//构造空的string类对象,即空字符串
	string s1;
	//用C-string来构造string类对象
	string s2("hello world");
	//string类对象中包含n个字符c
	string s3(5, 'x');
	//拷贝构造函数
	string s4(s2);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;

	return 0;
}

运行程序,构造类对象效果如下:


🎏string类对象析构函数

如下,C++中对于string类实现了1个析构函数:

该函数没有参数,没有返回值,在类对象生命周期结束后自动调用销毁类对象.


🎏string类对象赋值运算符重载函数

如下,C++98标准中对于string类实现了3个重载的赋值运算符重载函数:

接下来我们演示使用这三种常见的string类赋值运算符重载函数:

如下代码,分别按上述赋值运算符重载函数顺序调用了相应赋值运算符重载函数赋值了3次string类对象s4:

代码语言:javascript
复制
int main()
{
	//构造空的string类对象,即空字符串
	string s1;
	//用C-string来构造string类对象
	string s2("hello world");
	//string类对象中包含n个字符c
	string s3(5, 'x');
	//拷贝构造函数
	string s4(s2);

	cout << s4 << endl;

	s4 = s3;
	cout << s4 << endl;

	s4 = "ABCDEF";
	cout << s4 << endl;

	s4 = 'Y';
	cout << s4 << endl;

	return 0;
}

运行程序,赋值运算符重载效果如下:


📌string类对象的迭代遍历及元素访问操作

string类对象的迭代器相关函数共有8个,如下:

string类对象的元素访问相关函数共有四个,如下:

接下来我们演示学习几种常见的string类对象的迭代遍历及元素访问函数: 函数名称功能说明operator[]返回pos位置的字符,const string类对象调用begin+endbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器rbegin+rendbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器范围forC++支持更简洁的范围for的新遍历方式

🎏operator[]运算符重载

operator[]运算符重载定义:operator[]文档链接


operator[]遍历string类对象:

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;

int main()
{
	string st1("Hello world");
	
	for (size_t i = 0; i < st1.size(); i++)
	{
		cout << st1[i] << endl;
	}


	return 0;
}

operator[]遍历效果如下:


operator[]修改string类对象:

因为operator[]返回的是引用类型,因此可以利用其对string对象进行修改:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	
	for (size_t i = 0; i < st1.size(); i++)
	{
		++st1[i];
		cout << st1[i] << endl;
	}

	return 0;
}

operator[]重载访问string类对象和内置类型访问数组成员的区别:


🎏顺序迭代器begin+end

begin+end迭代器顺序遍历访问字符串:

begin()函数定义如下:

end()函数定义如下:


begin+end迭代器顺序遍历访问string类对象:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	//迭代器
	string::iterator it = st1.begin();
	while (it != st1.end())
	{
		cout << *it << endl;
		++it;
	}

	return 0;
}

begin+end迭代器顺序遍历访问效果如下:


begin+end迭代器修改string类对象:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	//迭代器
	string::iterator it = st1.begin();
	while (it != st1.end())
	{
		++(*it);

		cout << *it << endl;
		++it;
	}

	return 0;
}

begin+end迭代器修改string类对象效果如下:


🎏反向迭代器rbegin+rend

rbegin+rend逆序遍历访问string类对象:

rbegin()函数定义如下:

rend()函数定义如下:


使用rbegin+rend迭代器反向遍历访问string类对象:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");

	//反向迭代器
	string::reverse_iterator rit = st1.rbegin();
	while (rit != st1.rend())
	{
		cout << *rit << endl;
		++rit;
	}

	return 0;
}

rbegin+rend迭代器反向遍历访问string类对象效果如下:


使用rbegin+rend反向迭代器修改string类对象:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");

	//反向迭代器
	string::reverse_iterator rit = st1.rbegin();
	while (rit != st1.rend())
	{
		++(*rit);
		cout << *rit << endl;
		++rit;
	}

	return 0;
}

rbegin+rend反向迭代器修改string类对象效果如下:


🎏范围for

C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量, 第二部分则表示被迭代的范围。(注:知道数据类型的情况下可以不使用auto关键字自动推导类型)


范围for顺序访问string类对象:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");

	for (auto ch : st1)
	{
		cout << ch << endl;
	}

	return 0;
}

范围for顺序访问string类对象效果如下:


范围for修改string类对象:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");

	for (auto &ch : st1)
	{
		ch++;
		cout << ch << endl;
	}

	return 0;
}

范围for修改string类对象效果如下:


注:范围for在底层会替换成迭代器!


📌string类对象的容量操作

string类对象容量相关操作函数共有9个,如下:

接下来我们演示学习几种常见的string类对象的容量操作函数: 函数名称功能说明size返回字符串有效字符长度length返回字符串有效字符长度capacity返回空间总大小empty检测字符串释放为空串,是返回true,否则返回falseclear清空有效字符reserve为字符串预留空间resize将有效字符的个数改成n个,多出的空间用字符c填充

🎏size()函数

size()函数定义:


使用size()函数获取字符串有效字符长度:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	
	cout << st1.size() << endl;

	return 0;
}

size()函数效果如下:

🎏length()函数

length()函数定义:


使用length()函数获取字符串有效字符长度

代码语言:javascript
复制
int main()
{
	string st1("Hello world");

	cout << st1.length() << endl;

	return 0;
}

length()函数效果如下:

🎏capacity()函数

capacity()函数定义:


使用cipacity()函数获取string类对象当前存储空间总大小:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");

	cout << st1.size() << endl;
	cout << st1.capacity() << endl;

	return 0;
}

capacity()函数效果如下:


关于capacity:

  • 不同的编译器底层实现的扩容机制不同,vs初始长度为16,第一次扩容2倍,剩余每次扩容1.5倍;Linux初始长度按初始化的字符串来确定,之后每次扩容2倍

🎏empyt()函数

empty()函数定义:


使用empty()函数判断字符串是否为空串:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	string st2;

	cout << st1.empty() << endl;
	cout << st2.empty() << endl;

	return 0;
}

empty()函数效果如下:

🎏clear()函数

clear()函数定义:


使用clear()函数清空字符串:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	cout << st1.empty() << endl;

	st1.clear();
	cout << st1.empty() << endl;

	return 0;
}

clear()函数效果如下:


clear对size和capacity的影响:

代码语言:javascript
复制
int main()
{
	string st1("Hello world");
	cout << st1.size() << endl;
	cout << st1.capacity() << endl;

	st1.clear();
	cout << st1.size() << endl;
	cout << st1.capacity() << endl;

	return 0;
}

结论是:

一般而言,clear的改变会让size变成0,但不会影响capacity,因为要缩小容量,就需要重新再开辟空间,代价消耗太大,因此一般不会轻易改变capacity的大小:

🎏reserve()函数

reserve()函数定义:


使用reserve()函数更改类对象容量:

代码语言:javascript
复制
int main()
{
	string st1;
	cout << st1.capacity() << endl;

	st1.reserve(100);
	cout << st1.capacity() << endl;

	string st2("Hello this world");
	cout << st2.capacity() << endl;

	st2.reserve(100);
	cout << st2.capacity() << endl;


	return 0;
}

reserve()函数效果如下:

🎏resize()函数

resize()函数定义:


使用resize()函数调整字符串大小:

代码语言:javascript
复制
int main()
{
	string st1("Hello this world");
	cout << "st1:" << endl << st1 << endl;
	cout << st1.size() << endl;
	cout << st1.capacity() << endl;

	st1.reserve(100);
	cout << st1 << endl;
	cout << st1.size() << endl;
	cout << st1.capacity() << endl << endl ;

	string st2("Hello this world");
	cout << "st2:" << endl << st2 << endl;
	cout << st2.size() << endl;
	cout << st2.capacity() << endl;

	st2.resize(100);
	cout << st2 << endl;
	cout << st2.size() << endl;
	cout << st2.capacity() << endl;

	return 0;
}

resize()函数效果如下:

resize在调整容量时也可以用指定的字符来填充,如:

注意:

  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类对象的字符串修改操作

string类对象的字符串修改函数共有21个,如下:

常用的字符串修改操作: 函数名称功能说明push_back在字符串后尾插字符cappend在字符串后追加一个字符串operator+=在字符串后追加字符串strc_str返回C格式字符串find+nops从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置substr在str中从pos位置开始,截取n个字符,然后将其返回

🎏push_back()函数

push_back()函数定义:


使用push_back()函数在string类对象后追加字符:

代码语言:javascript
复制
int main()
{
	string st1("Hello worl");
	cout << st1 << endl;
	cout << st1.size() << endl;

	st1.push_back('d');
	cout << st1 << endl;
	cout << st1.size() << endl;

	return 0;
}

push_back()函数效果如下:

🎏append()函数

append()函数定义:

append()函数一共实现了7个重载函数,但我们日常对于要在字符串后追加内容的场景使用operator+=的次数更多,因此后面会重点介绍operator+=:


使用append()函数在string类对象后追加内容:

代码语言:javascript
复制
int main()
{
	string st1("Hello worl");
	cout << st1 << endl;
	cout << st1.size() << endl;

	st1.append("ddddd!");
	cout << st1 << endl;
	cout << st1.size() << endl;

	return 0;
}

append()函数效果如下:

🎏operator+=()函数

operator+=()函数定义:


使用operator+=()函数在string类对象后追加string类对象内容:

代码语言:javascript
复制
int main()
{
	string st1("Hello ");
	string st2("world");
	cout << st1 << endl;
	cout << st2 << endl;

	st1 += st2;
	cout << st1 << endl;

	return 0;
}

operator+=()函数效果如下:


使用operator+=()函数在string类对象后追加常量字符串内容:

代码语言:javascript
复制
int main()
{
	string st1("Hello ");
	cout << st1 << endl;

	st1 += "world";
	cout << st1 << endl;

	return 0;
}

operator+=()函数效果如下:


使用operator+=()函数在string类对象后追加常量字符内容:

代码语言:javascript
复制
int main()
{
	string st1("Hello ");
	cout << st1 << endl;

	st1 += '!';
	cout << st1 << endl;

	return 0;
}

operator+=()函数效果如下:

🎏c_str()函数

c_str函数定义:

使用c_str()函数返回c格式字符串:

c_str主要是考虑到部分项目中不兼容C++只能转换成C的情况,如下,fopen函数不支持传入string类:

如果想要在C++文件中使用C语言函数且参数是string类的话,就可以调用c_str()函数将string类对象转换为C语言字符串:

代码语言:javascript
复制
int main()
{
	string filename("Hello");
	fopen(filename.c_str(), "r");

	return 0;
}

c_str()函数效果如下:

find+nops函数 find函数定义:

nops函数定义:

使用find+nops函数在string类对象pos位置开始向后寻找字符c: find+nops函数效果如下:

rfind()函数 rfind()函数定义:

使用rfind()函数在string类对象pos位置开始向前寻找字符c: rfind()函数效果如下:

substr()函数 substr()函数定义:

使用substr()函数在string类对象中从pos位置开始,截取n个字符并返回: substr()函数效果如下:


string类的非成员函数

非成员函数重载共有6个,如下:

常用的非成员函数 函数名称功能说明operator+尽量少用,因为传值返回,导致深拷贝效率低operator>>输入运算符重载operator<<输出运算符重载getline获取一行字符串relational operators大小比较

🎏operator+()函数

operator+()函数定义:


使用operator+()函数完成string类对象和常量字符串相加:

代码语言:javascript
复制
int main()
{
	string st1("Hello ");
	string st2 = st1 + "world";
	cout << st2 << endl;

	return 0;
}

operator+()函数效果如下:

🎏operator>>()函数

operator>>()函数定义:


使用operator>>()函数从流中提取字符串:

代码语言:javascript
复制
int main()
{
	string st1;
	cin >> st1;

	cout << st1 << endl;

	return 0;
}

operator>>()函数效果如下:

🎏operator<<()函数

operator<<()函数定义:


使用operator<<()函数在string类对象后追加内容:

代码语言:javascript
复制
int main()
{
	string st1("hello!");

	cout << st1;

	return 0;
}

operator<<()函数效果如下:

🎏getline()函数

getline()函数定义:


使用getline()函数将行从流中获取到字符串:

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

	std::getline(cin,st1);

	cout << st1 << endl;

	return 0;
}

getline()函数效果如下:(使用getline流插入字符时可以无视空格,直到遇到回车才截止)

🎏relational operators

relational operators定义:


使用relational operators比较字符串:

代码语言:javascript
复制
int main()
{
	string st1("hello");
	string st2("world");

	cout << (st1 > st2) << endl;
	cout << (st1 >= st2) << endl;
	cout << (st1 == st2) << endl;
	cout << (st1 != st2) << endl;
	cout << (st1 <= st2) << endl;
	cout << (st1 < st2) << endl;

	return 0;
}

relational operators效果如下:

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • string类简介
  • string类常用接口(成员函数)
    • 📌string类对象默认成员函数
      • 🎏string类对象构造函数
      • 🎏string类对象析构函数
      • 🎏string类对象赋值运算符重载函数
    • 📌string类对象的迭代遍历及元素访问操作
      • 🎏operator[]运算符重载
      • 🎏顺序迭代器begin+end
      • 🎏反向迭代器rbegin+rend
      • 🎏范围for
    • 📌string类对象的容量操作
      • 🎏size()函数
      • 🎏length()函数
      • 🎏capacity()函数
      • 🎏empyt()函数
      • 🎏clear()函数
      • 🎏reserve()函数
      • 🎏resize()函数
    • string类对象的字符串修改操作
      • 🎏push_back()函数
      • 🎏append()函数
      • 🎏operator+=()函数
      • 🎏c_str()函数
    • string类的非成员函数
      • 🎏operator+()函数
      • 🎏operator>>()函数
      • 🎏operator<<()函数
      • 🎏getline()函数
      • 🎏relational operators
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档