第六章:string类

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 为什么学习string类
    • C语言中的字符串
    • ASCII
    • Unicode
      • **UTF-8**
      • UTF-16
      • UTF-32
    • GBK
  • 标准库中的string类
    • string类
      • 总结
    • string类的常用接口说明
      • 1. string类对象的常见构造
      • 2. string类对象的容量操作
      • 3. string类对象的访问及遍历操作
      • 4. string类对象的修改操作
      • 5. string类非成员函数
      • 6. string类对象的字符串的转换(在C++11适用)
  • vs和g++下string结构的说明
        • vs下string的结构
        • g++下string的结构


前言

string是字符序列的类


C++文档

为什么学习string类

C语言中的字符串

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

ASCII

ASCII (American Standard Code for Information Interchange):美国信息交换标准代码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符。

**在计算机中存储和显示英语信息

26个大小写字母、数字、标点符号

建立一个符号和编码对应关系的映射表

用一个字节的大小存储7位编码,最高位不用,一个符号→一个字节**

在这里插入图片描述

int main()
{
	char str1[] = "apple";	

	char str2[] = "好好";

	cout << sizeof(str1) << endl;
		
	cout << sizeof(str2) << endl;

	return 0;
}

在这里插入图片描述

int main()
{

	char str2[] = "好好";

	cout << sizeof(str2) << endl;

	str2[3]--;
	cout << str2 << endl;

	str2[3]--;
	cout << str2 << endl;

	str2[3]++;
	cout << str2 << endl;
	
	str2[3]++;
	cout << str2 << endl;

	return 0;
}

在这里插入图片描述

Unicode

统一码(Unicode),也叫万国码单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。

统一码是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求

UTF-8

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。统一码的最大码位0x10FFFF也只有21位。

在这里插入图片描述

UTF-16

UTF-16编码以16位无符号整数为单位。我们把统一码编码记作U。

UTF-32

UTF-32编码以32位无符号整数为单位。统一码的UTF-32编码就是其对应的32位无符号整数。

GBK

GBK全称《汉字内码扩展规范》(GBK即“国标”、“扩展”汉语拼音的第一个字母,英文名称:Chinese Internal Code Specification)。

GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
在这里插入图片描述

标准库中的string类

string类

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

string类的文档

在这里插入图片描述

string类用utf-8编码,按单字节处理
u16string用utf-16编码
u32string用utf-32编码
wstring类按两字节处理

在这里插入图片描述

编码:
计算机中存储只有二进制0、1,用对应的ASCII表来表示文字(支持英文的)其中ASCII表是对256个值建立一个对应的表示值
在早期只有欧美国家使用计算机(早期的计算机中只能表示英文,不能表示其他国家的文字),后来全世界各个国家都开始用计算机了,需要建立自己的编码表
在Linux中常用utf-8、utf-16、utf-32
在Windows中常用gbk

总结

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

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

  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;

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

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

string类的常用接口说明

string类的常用接口

1. string类对象的常见构造

(constructor)函数名称功能说明
string() (重点)构造空的string类对象,即空字符串
string(const char* s) (重点)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string&s) (重点)拷贝构造函数
void Teststring()
{
    string s1; // 构造空的string类对象s1
    string s2("hello bit"); // 用C格式字符串构造string类对象s2
    string s3(s2); // 拷贝构造s3
}

2. string类对象的容量操作

函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小,但不包含’\0’
empty (重点)检测字符串释放为空串,是返回true,否则返回false
clear (重点)清空有效字符
reserve (重点)为字符串提前预留空间
resize (重点)将有效字符的个数该成n个,多出的空间用字符c填充

在这里插入图片描述

注意:
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不会改变容量大小。
5. 在Windows中容量是以大约1.5倍增容的,在Linux中容量是以大约2倍增容的
6. reserve的作用:如果知道需要多少空间,直接一次性开好,避免增容,提高效率
7. resize的作用:既能开好空间,又能对这些空间初始化

string容量相关方法使用代码演示

3. string类对象的访问及遍历操作

函数名称功能说明
operator[] (重 点)返回pos位置的字符,const string类对象调用
begin+ endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置(‘\0’)的迭代器
rbegin + rendrbegin获取最后一个字符的迭代器 + rend获取开头一个字符前一个位置的迭代器
范围forC++11支持更简洁的范围for的新遍历方式,底层是用迭代器

string中元素访问及遍历代码演示

int main()
{
    string s1("hello world");
    string::iterator it = s1.begin();
    //正向迭代器
    while (it != s1.end())
    {
	    cout << *it << " ";
	    it++;
    }
	string::reverse_iterator rit = s1.rbegin();
    //反向迭代器
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		rit++;
        //都是++
	}
  
    for (auto ch : s1)
	{
		cout << ch << " ";
	}

	cout << endl;
  
	return 0;
}
void Func1(const string& s)
{	
	//遍历和读容器的数据,不能写
	//string::const_iterator it = s.cbegin();
    auto it = s.cbegin();
    //静态正向迭代器
	while (it != s.end())
	{
		cout << *it << " ";
        it++;
	}

	cout << endl;
}
void Func2(const string& s)
{	
    
	//string::const_reverse_iterator it = s.crbegin();
    auto it = s.crbegin();
    //静态反向迭代器
	while (it != s.rend())
	{
		cout << *it << " ";
        it++;
	}

	cout << endl;
}
int main()
{
	string s1("hello world");
	string::iterator it = s1.begin();
    //iterator 迭代器 是属于类的一种类型
	while (it != s1.end())
	{
		cout << *it << " ";
		it++;
	}

	for (auto ch : s1)
	{
		cout << ch << " ";
	}
    
    Func1();
    
    Func2();

	cout << endl;
	
	return 0;
}

总结:
迭代器是一个行为像指针的东西,有可能是指针,也有可能不是指针
迭代器可以用统一类似的方式去访问修改容器
begin()返回的是第一个有效数据位置的迭代器,end()返回的是最后一个有效数据的下一个位置的迭代器
rbegin()返回的是最后个有效数据位置的迭代器,rend()返回的是第一个有效数据的前一个位置的迭代器
所有的容器都支持用迭代器,所以迭代器才是容器通用的访问方式(vector/string这样的结构支持下标+[]去访问,而像list、map这样的就不支持了),虽然迭代器在所有数据结构都是可以使用的,但[]+下标指适用顺序表。
const对象要用const迭代器,只读,不能写
operator[]和at的区别:operator[]如果发生越界访问会报断言错误(assert),而at会报异常(需要捕获异常)

4. string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+= (重点)在字符串后追加字符串str
c_str(重点)返回C格式字符串
find + npos(重点)从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

string中插入和查找等使用代码演示

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

int main()
{
	string s1("world");

	s1.insert(0, "hello");

	//不推荐使用insert,效率低
	//s1.insert(5, 1, ' ');
	//s1.insert(5, " ");
	string::iterator it = s1.begin();
	s1.insert(it+5, ' ');
	cout << s1 << endl;
	return 0;
}
int main()
{
	//不推荐使用erase,效率低
	string s1("hello world");
	//s1.erase(5, 1);

	string::iterator it = s1.begin();
	//s1.erase(it + 5);

	//s1.erase(5);
	s1.erase(5, 6);
	cout << s1 << endl;

}
int main()
{
	//string s1("hello world");
	//s1.replace(5, 1, "%%d");//扩容+移动数据
	//cout << s1 << endl;、

	string s1("hello world i love you");
	size_t num = 0;
	for (auto ch : s1)
	{
		if (ch == ' ')
		{
			num++;
		}
	}
	//提前开空间,避免replace时扩容
	s1.reserve(2* num + s1.size());
	size_t pos = s1.find(' ');
	while(pos != string::npos)
	{	
		s1.replace(pos, 1, "%20");
		pos = s1.find(' ', pos + 3);
	}
	cout << s1 << endl;
}

//空间换时间
int main()
{
	string s1("hello world i love you");
	string newStr;
	size_t num = 0;
	for (auto ch : s1)
	{
		if (ch == ' ')
		{
			num++;
		}
	}
	//提前开空间,避免replace时扩容
	s1.reserve(2* num + s1.size());
	for (auto ch : s1)
	{
		if (ch != ' ')
			newStr += ch;
		else
			newStr += "%20";
	}
	s1 = newStr;
	cout << newStr << endl;
}
int main()
{
	string s1("xxx");
	string s2("yyy");

	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;

	swap(s1, s2);
	cout << s1 << endl;
	cout << s2 << endl;
	 
}

在这里插入图片描述

5. string类非成员函数

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

在这里插入图片描述

在这里插入图片描述

cin遇到空格和换行就会分割(或结束),而getline遇到空格不会分割(或结束)遇到换行才分割(或结束)

6. string类对象的字符串的转换(在C++11适用)

在这里插入图片描述

vs和g++下string结构的说明

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节.

vs下string的结构

string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:

  • 当字符串长度小于16时,使用内部固定的字符数组来存放

  • 当字符串长度大于等于16时,从堆上开辟空间

union _Bxty
{ // storage for small buffer or pointer to larger one
	value_type _Buf[_BUF_SIZE];
	pointer _Ptr;
	char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。
其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量最后:还有一个指针做一些其他事情。
故总共占16+4+4+4=28个字节。
在这里插入图片描述

g++下string的结构

G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:

  • 空间总大小

  • 字符串有效长度

  • 引用计数

struct _Rep_base
{
	size_type        _M_length;
	size_type        _M_capacity;
	_Atomic_word      _M_refcount;
};
  • 指向堆空间的指针,用来存储字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1uFFi6yM-1689733417126)(https://flowus.cn/preview/cc560c88-e3f5-4381-b6fc-3a21c3afb6f4)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/42130.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nginx正向代理和反向代理详解

目录 一、什么是正向代理&#xff1f; 二、什么是反向代理&#xff1f; 三、正向代理和反向代理的作用 一、什么是正向代理&#xff1f; 正向代理&#xff0c;“它代理的是客户端”&#xff0c;是一个位于客户端和目标服务器之间的服务器&#xff0c;为了从目标服务器取得内…

Spring Cloud+Spring Boot+Mybatis+uniapp+前后端分离实现知识付费平台

Java版知识付费-轻松拥有知识付费平台 多种直播形式&#xff0c;全面满足直播场景需求 公开课、小班课、独立直播间等类型&#xff0c;满足讲师个性化直播场景需求&#xff1b;低延迟、双向视频&#xff0c;亲密互动&#xff0c;无论是互动、答疑&#xff0c;还是打赏、带货、…

【java爬虫】将优惠券数据存入数据库排序查询

本文是在之前两篇文章的基础上进行写作的 (1条消息) 【java爬虫】使用selenium爬取优惠券_haohulala的博客-CSDN博客 (1条消息) 【java爬虫】使用selenium获取某宝联盟淘口令_haohulala的博客-CSDN博客 前两篇文章介绍了如何获取优惠券的基础信息&#xff0c;本文将获取到的…

和chatgpt学架构02-环境搭建

目录 1 安装vs code2 vs code功能介绍3 安装nodejs4 安装vue5 在vs code打开工程总结 我们在上一篇 技术选型 里咨询了chatgpt前后端的框架选择和数据库的选择。有了框架之后就需要选择合适的开发工具了&#xff0c;继续咨询一下chatgpt 我现在选型&#xff0c;前端使用vue&am…

Mac 谷歌浏览器选中查看悬浮出现的元素样式

Mac 谷歌浏览选中查看悬浮出现的元素样式 1. Mac 暂停脚本执行快捷键 command \或F8 2.以斗鱼主站下载悬浮面板为例 3. 操作步骤 &#xff08;1&#xff09;打开控制台&#xff0c;选中源代码 &#xff08;2&#xff09;鼠标选中下载&#xff0c;让面板悬浮出来 &#xf…

【GitOps系列】K8s极简实战

文章目录 示例应用介绍部署应用到k8s 如何使用命名空间隔离团队及应用环境&#xff1f;如何为业务选择最适合的工作负载类型&#xff1f;如何解决服务发现问题&#xff1f;如何迁移应用配置&#xff1f;如何将集群的业务服务暴露外网访问&#xff1f;如何保障业务资源需求和自动…

Selenium自动化之弹窗处理

1.前言 我们在使用Selenium做Web自动化测试时&#xff0c;页面经常出现弹窗&#xff0c;如果不处理后续的测试脚本就无法正常运行&#xff0c;今天我们就带大家一起来学习如何处理Web页面上的弹窗。 2.Web页面弹窗的分类 弹窗通常有3种&#xff1a;Alert类型弹框、Confirm类…

【文生图系列】stable diffusion webui 汉化(双语)教程

文章目录 安装双语插件下载json源文件设置双语 这篇博文记录于我成功安装双语插件之后&#xff0c;所以以下的示例页面均是双语。汉化教程分为三步&#xff0c;安装插件&#xff0c;JSON源文件下载和最后一步的双语设置。 安装双语插件 在扩展&#xff08;extensions&#xf…

【已解决】idea使用debug启动一直卡着不动

debug启动时一直卡着不动出现下图提示&#xff0c;但是正常启动又可以启动 翻译结果是&#xff1a;方法断点可能会大大降低调试速度。很明显&#xff0c;有断点的位置没加对或者误加断点了&#xff0c;以下是解决方法。 打开 .idea文件夹&#xff0c;找到workspace.xml文件 找…

引入Vue的方式

1.cdn引入 <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

配置需求分类中的科目分配

其中科目分配的内容都为灰色无法修改 结果是在科目分配里面单独维护的&#xff1a; 路径&#xff1a;销售分销-基本功能-科目分配/成本-维护成本科目分配的需求类别

【Ceph集群应用】Ceph对象存储系统之RGW接口详解

Ceph对象存储系统之RGW接口详解 1.创建Ceph对象存储系统RGW接口2. 开启httphttps,更改监听端口3. 更改监听端口4.S3接口访问测试5.实验中遇到的故障案例 接上文基于ceph-deploy部署Ceph集群详解 1.创建Ceph对象存储系统RGW接口 &#xff08;1&#xff09;对象存储概念 对象存…

广州市番禺区委领导一行莅临和鲸科技考察交流

7月18日下午&#xff0c;广州市番禺区区委常委、组织部部长、人才工作局局长唐力明&#xff0c;组织部副部长、两新工委书记罗翌洁及组织部其他相关领导一行莅临和鲸科技开展实地考察与调研&#xff0c;国投科创广州基地负责人、海创人才南方创业服务中心常务副秘书长徐斌&…

详解C#开发Android应用程序的流程

Android系统一下子铺天盖地而来&#xff0c;让人目不暇接。兴奋的同时也让部分开发人员犯难了&#xff01;要知道从熟知的Wince、Mobile开发语言C#跨越到RFID-Android的Java。可不是一朝一夕就能完成的。就好比你的乾坤大挪移已经第七层了&#xff0c;却忽然要你从易筋经从头练…

Beyond Compare 代码比较工具

一、下载 官网下载地址&#xff1a; https://www.scootersoftware.com/download.php 选择 Windows 系统&#xff0c;简体中文版本&#xff0c;点击下载。 下载完成 二、安装 步骤1&#xff1a;双击安装包 步骤2&#xff1a;进入安装向导&#xff0c;点击下一步 步骤3&a…

微信小程序事件点击跳转页面的五种方法

第一种:标签 这是最常见的一种跳转方式,相当于html里的a标签 <navigator url"/pages/main/main"></navigator>第二种:wx.navigateTo({})方法 1.前端wxml <button bindtap"getCeshi" type"primary"> 测试按钮 </button>…

php连接上mysql数据库该的配置方法

用mysql官方的管理工具workbench&#xff1a; 打开导出界面后&#xff0c;下一步&#xff0c;选择csv格式&#xff0c;导出后excel就能打开了 如果你需要在程序代码中导出&#xff0c;需要找到对应代码的excel处理库。 如php 的 phpExcel( 最新版已更名为 phpoffice/phpspread…

思维决定发展,测试人也不例外

最近特别懒&#xff0c;不想码字&#xff0c;原本写作就很差&#xff0c;更是退化严重。社招和校招面试过很多人&#xff0c;从十年前自己还很弱的时候学着面试&#xff0c;到数百次面试积累之后&#xff0c;面对候选人的时候&#xff0c;我的内心依然有些许紧张&#xff0c;非…

域内信息收集

将网络中多台计算机逻辑上组织到一起进行集中管理&#xff0c;这种区别于工作组的逻辑环境叫 做域。域是由域控制器(Domain Controller)和成员计算机组成&#xff0c;域控制器就是安装了活动 目录(Active Directory)的计算机。活动目录提供了存储网络上对象信息并使用网络使用该…

132、仿真-基于51单片机主从串口通信家用防盗报警器设计(程序+Proteus仿真+流程图等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、设计功能 二、Proteus仿真图​编辑 三、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&#xff1…