C++中string类的使用

目录

一.string类

1.1为什么学习string类?

1.2.标准库中的string类

二.string对象的元素访问

 2.1.1使用operator[]与at实现访问

2.1.2正向迭代器访问

2.1.3反向迭代器访问

2.1.4const正向迭代器(不能修改)

2.1.5const反向迭代器(不能修改)

2.1.6范围for

三.string类对象的常见构造

三. string类对象的容量操作

四. string类对象的修改操作

 find

五.string类非成员函数

六.将string对象int互相转换

6.1stoi 将string里第一次遇到的数字字符转换成int

6.2, to_string 将数字转化成string对象

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

7.1vs下string的结构

7.2g++下string的结构


一.string类

1.1为什么学习string类?

C 语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便, C 标准库中提供了一些 str 系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP 的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
OJ 中,有关字符串的题目基本以 string 类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本 都使用string 类,很少有人去使用 C 库中的字符串操作函数。

1.2.标准库中的string类

string类的文档介绍

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

3. string 在底层实际是: basic_string 模板类的别名, typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字节或者变长字符的序列。 使用string类时,必须包含#include头文件以及using namespace std;

二.string对象的元素访问

 2.1.1使用operator[]与at实现访问

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello");//构造for (size_t i = 0; i < s.size(); i++)//读{cout << s[i] << "  ";}cout << endl;for (size_t i = 0; i < s.size(); i++){cout << s.at(i) << "  ";}cout << endl;for (size_t i = 0; i < s.size(); i++)//写,at同理{cout << s[i]+=1 << "  ";}}

operator[]与at的区别:

operator[]在元素越界访问时,采用断言,at采用抛出异常

2.1.2正向迭代器访问

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::iterator it = s.begin();while (it != s.end())//读{cout << *it << "  ";it++;}cout << endl;it = s.begin();while (it != s.end())//写{*it += 1;cout << *it << "  ";}cout << endl;return 0;
}

2.1.3反向迭代器访问

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::reverse_iterator it = s.rbegin();while (it != s.rend())//读{cout << *it << "  ";it++;}cout << endl;it = s.rbegin();while (it != s.rend())//写{*it += 1;cout << *it << "  ";}cout << endl;return 0;
}

2.1.4const正向迭代器(不能修改)

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::const_iterator it = s.begin();while (it != s.end())//读{cout << *it << "  ";it++;}cout << endl;return 0;
}

2.1.5const反向迭代器(不能修改)

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::const_reverse_iterator it = s.rbegin();while (it != s.rend())//读{cout << *it << "  ";it++;}cout << endl;return 0;
}

2.1.6范围for

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");for(auto ch:s)//无法修改{cout<<ch<<"  ";}for(auto& ch:s)//可以修改{ch+=1;cout<<ch<<"  ";}return 0;
}

三.string类对象的常见构造

string()   重点无参构造函数
string(const char* s)  重点用字符串构造对象
string(size_t n,char c)  重点用n个字符构造对象
string(const string& s) 重点拷贝构造
string(const string& str,size_t pos,size_t len=npos)用str从下标(包括)之后len长度的内容,构造对象
string(const char* s,size_t n)用字符串前n个构造对象

template <class InputIterator first,InputIterator last>

string(InputIterator first,InputIterator last)

迭代器区间构造对象

注:第四个构造方法,中的npos,是string类中的一个被static修是的,类型为size_t(无符号整形),值为-1

#include<iostream>
#include<string>
using namespace std;int main()
{string s1;//无参构造string s2("abcdefg");//用字符串构造对象string s3(5, 's');//string类对象中包含n个字符string s4(s2);//拷贝构造string s5(s2, 0, 3);//用str从下标(包括)之后len长度的内容,构造对象string s6("abcdefg", 3);//用字符串前n个构造对象string s7(s6.begin(), s6.end());//迭代器区间构造对象cout << "s1=" << s1 << endl;cout << "s2=" << s2 << endl;cout << "s3=" << s3 << endl;cout << "s4=" << s4 << endl;cout << "s5=" << s5 << endl;cout << "s6=" << s6 << endl;cout << "s7=" << s7 << endl;return 0;
}

三. string类对象的容量操作

size (重点)返回字串有效字符长度
length返回字符串有效长度
capacity  返回空间总大小
empty (重点)检测字符串是否为空串,是返回true,否则返回false
clear (重点)清空有效字符
reserve (重点)为字符串预留空间
resize (重点)将有效字符个数改成n个,多出的空间用字符c填充

1.reverse(修改总容量)

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");cout << s.size() << "  " << s.capacity() << endl;s.reserve(100);cout << s.size() << "  " << s.capacity() << endl;s.reserve(10);cout << s.size() << "  " << s.capacity() << endl;return 0;
}

reserve用于预开空间,如果开辟的空间小于原空间,并不会改变容量

2.resize(调整size)
#include<iostream>
#include<string>
using namespace std;int main()
{//resize(n)// resize(size_t n,char x)//分三种情况//1.  n<size//2.  n>size && n<=capacity//3.  n>capacitystring s("hello world");s.resize(10);//cout << s.size() << "  " << s.capacity() << "  " << s<<endl;s.resize(17);//将size改为17,多出来的用'\0'填充cout << s.size() << "  " << s.capacity() << "  " << s<<endl;s.resize(40, 'x');//将size改为40,多出来的位置用'x'填充cout << s.size() << "  " << s.capacity() << "  " << s<<endl;return 0;
}

resize用于调整size,当n大于容量是,会扩容,并用对于的字符填充。

当n>size && n< 容量时,用对应的字符填充多出来的

当n<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类对象的修改操作

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

 find

//从pos位置开始找,str
size_t find (const string& str, size_t pos = 0) const noexcept;//从pos位置开始找字符串第一次出现的下标,若不存在返回npos	
size_t find (const char* s, size_t pos = 0) const;//从pos位置找字符串s的前n个第一次出现的下标,不存在返回npos
size_t find (const char* s, size_t pos, size_type n) const;size_t find (char c, size_t pos = 0) const noexcept;

通常finf与substr配合使用对找一个网址对应的协议,域名,地址

#include<iostream>
#include<string>
using namespace std;int main()
{
//string s3("https://legacy.cplusplus.com/reference/string/string/rfind/");string s3("ftp://www.baidu.com/?tn=65081411_1_oem_dg");// 协议// 域名// 资源名string sub1, sub2, sub3;size_t i1 = s3.find(':');if (i1 != string::npos)sub1 = s3.substr(0, i1);//查找协议elsecout << "没有找到i1" << endl;size_t i2 = s3.find('/', i1+3);if (i2 != string::npos)sub2 = s3.substr(i1+3, i2-(i1+3));//查找域名elsecout << "没有找到i2" << endl;sub3 = s3.substr(i2 + 1);//查找地址cout << sub1 << endl;cout << sub2 << endl;cout << sub3 << endl;
}

五.string类非成员函数

operator+  
尽量少用,因为传值返回,导致深拷贝效率低
operator>> (重点)
输入运算符重载
operator<< (重点)
输出运算符重载
getline (重点)
获取一行字符串
流提取不能接受空格和换行,需要用接受带有空格的字符串时,可以用getline
getline
istream& getline(istream& in, string&str, char delim);//从流提取中提取字符串到str中,直到delim或'\n'istream& getline(istream& in,string& str, char);//从流提取中取字符串到str

六.将string对象int互相转换

6.1stoi 将string里第一次遇到的数字字符转换成int

将一个string对象转化成int类型的数字
idx不传参为nullptr,表示不使用这个参数,反之,&idx指向string对象数字字符的后一个位置

6.2, to_string 将数字转化成string对象

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

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

7.1vs下string的结构

string 总共占 28 个字节 ,内部结构稍微复杂一点,先是 有一个联合体,联合体用来定义 string 中字
符串的存储空间
当字符串长度小于 16 时,使用内部固定的字符数组来存放
当字符串长度大于等于 16 时,从堆上开辟空间
union _Bxty
{ // storage for small buffer or pointer to larger onevalue_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 个字节。

7.2g++下string的结构 ​​​​​​​

G++ 下, string 是通过写时拷贝实现的, string 对象总共占 4 个字节,内部只包含了一个指针,该指
针将来指向一块堆空间,内部包含了如下字段:
空间总大小
字符串有效长度
引用计数
struct _Rep_base
{size_type _M_length;size_type _M_capacity;_Atomic_word _M_refcount;
};
指向堆空间的指针,用来存储字符串。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

垃圾收集算法和各种垃圾收集器的实现

深入理解Jvm虚拟机第三章 二、对象已死&#xff1f;3.2.1 引用计数算法3.2.2 可达性分析算法3.2.3 再谈引用3.2.4 生存还是死亡3.2.5 回收方法区 三、垃圾收集算法3.3.1 分代收集理论3.3.2 标记-清除算法3.3.3 标记-复制算法3.3.4 标记-整理算法 四、HotSpot的算法细节实现3.4.…

C# WPF上位机开发(串口界面设计)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 如果只是把上位机看成是纯软件开发&#xff0c;本身不和硬件打交道的话&#xff0c;那么这就把上位机的操作范围给限定死了。事实上&#xff0c;上…

数据库系统概论期末经典大题讲解(范式提升、求闭包、求主码)

上一次我们介绍了数据库中关系代数查询&#xff0c;从选择、投影到连接等操作符&#xff0c;探索了数据库查询 大家可以移步我的文章&#xff1a;数据库系统概论期末经典大题讲解&#xff08;用关系代数进行查询&#xff09;-CSDN博客 今天&#xff0c;我们将继续沿着数据库系统…

《python每天一小段》--12 数据可视化《1》

欢迎阅读《Python每天一小段》系列&#xff01;在本篇中&#xff0c;将使用Python Matplotlib实现数据可视化的简单图形。 一、概念 Matplotlib是一个流行的Python数据可视化库&#xff0c;它提供了丰富的绘图功能&#xff0c;可以创建各种类型的图表&#xff0c;包括折线图、…

Spring框架学习:Bean生命周期

目录 SpringBean的生命周期 Bean实例属性填充 三级缓存 常用的Aware接口 Spring IoC容器实例化Bean总结 SpringBean的生命周期 Spring Bean的生命周期是从 Bean 实例化之后&#xff0c;即通过反射创建出对象之后&#xff0c;到Bean成为一个完整对象&#xff0c;最终存储到…

【MyBatis系列】MyBatis字符串问题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

SpringBoot + Spring Cloud Alibaba + Nacos实现服务管理

1、参考文档 Spring Cloud Alibaba参考文档 https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html Spring Cloud Alibaba官方文档 https://github.com/alibaba/spring-cloud-alibaba/wiki/ 2、引入 Alibaba 依赖 每个 SpringBoot 都有对应的…

javascript实现Stack(栈)数据结构

上一篇文章我们理解了List这种数据结构&#xff0c;知道了它的特点和一些使用场景&#xff0c;这篇文章我们就来看一下栈这种数据结构&#xff0c;这里的栈可不是客栈哦&#xff0c;哈哈 栈其实和List非常像&#xff0c;使用javascript实现都是基于数组来实现 尝试理解Stack …

windows系统和虚拟机上ubuntu系统通过虚拟串口进行通信

本文的目的是实现windows系统和虚拟机上安装的ubuntu通过串口进行通信。为了直观观测串口收发数据的内容&#xff0c;需要在windows系统和ubuntu系统使用串口助手来进行监听。windows系统端用的监听工具是串口助手SSCOM&#xff0c;ubuntu系统端使用的串口助手是CuteCom。 ubu…

OpenCL学习笔记(一)开发环境搭建(win10+vs2019)

前言 异构编程开发&#xff0c;在高性能编程中有重要的&#xff0c;笔者本次只简单介绍下&#xff0c;如何搭建简单的开发环境&#xff0c;可以供有需要的小伙伴们开发测试使用 一、获取opencl的sdk库 1.使用cuda库 若本机有Nvidia的显卡&#xff0c;在安装cuda库后&#x…

如何提高大模型在超长上下文的表现?Claude实验表明加一句prompt立即提升效果~

本文来自DataLearnerAI官方网站&#xff1a;如何提高大模型在超长上下文的表现&#xff1f;Claude实验表明加一句prompt立即提升效果~ | 数据学习者官方网站(Datalearner)https://www.datalearner.com/blog/1051701947131881 Claude 2.1版本的模型上下文长度最高拓展到200K&am…

【Flink系列四】Window及Watermark

3.1、window 在 Flink 中 Window 可以将无限流切分成有限流&#xff0c;是处理有限流的核心组件&#xff0c;现在 Flink 中 Window 可以是时间驱动的&#xff08;Time Window&#xff09;&#xff0c;也可以是数据驱动的&#xff08;Count Window&#xff09;。 Flink中的窗口…

Java基础-开发流程以及HelloWorld程序

目录 1. Java的开发流程2. HelloWorld 1. Java的开发流程 开发Java程序&#xff0c;需要三个步骤&#xff1a;编写代码&#xff0c;编译代码&#xff0c;运行代码 2. HelloWorld 编写代码 public class HelloWorld {public static void main(String[] args) {System.out.pri…

Ribbon 饥饿加载

Ribbon默认是采用懒加载&#xff0c;即第一次访问时才会去创建LoadBalanceClient&#xff0c;请求时间会很长而饥饿加载则会在项目启动时创建&#xff0c;降低第一次访问的耗时&#xff0c;通过下面配置开启饥饿加载: 一、懒加载 Ribbon 默认为懒加载即在首次启动Application…

代码随想录二刷 |二叉树 | 二叉树的层序遍历

代码随想录二刷 &#xff5c;二叉树 &#xff5c; 二叉树的层序遍历 题目描述解题思路代码实现 题目描述 102.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例…

Java实现Socket聊天室

一、网络编程是什么&#xff1f; 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;进行数据传输。 应用场景&#xff1a;即时通讯、网游对战、金融证券、国际贸易、邮件、等等。 不管是什么场景&#xff0c;都是计算机与计算机之间通过网络进行数据传输。 …

软件测试之接口测试自动化(详解版)

本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接口测试领域的一些方法和心得&#xff0c;希望大家一起讨论和分享&#xff0c;内容包括但不仅限于&#xff1a; 服务端接口测试介绍接口测试自动化介绍接口测试自动化实践关于接口测试自动化的思考…

质量工程化,交付快速化

质量和速度之间权衡让人很难取舍&#xff0c;而通过推进质量工程&#xff0c;以系统化的方式识别和优化系统痛点&#xff0c;可以帮助团队构建既快又好的精益软件生产系统。原文: Quality Engineered, Speed Delivered 所有人都想要更快的速度。 但需要解决复杂问题: 权衡质量会…

(二)五种最新算法(SWO、COA、LSO、GRO、LO)求解无人机路径规划MATLAB

一、五种算法&#xff08;SWO、COA、LSO、GRO、LO&#xff09;简介 1、蜘蛛蜂优化算法SWO 蜘蛛蜂优化算法&#xff08;Spider wasp optimizer&#xff0c;SWO&#xff09;由Mohamed Abdel-Basset等人于2023年提出&#xff0c;该算法模型雌性蜘蛛蜂的狩猎、筑巢和交配行为&…

线上盲盒小程序,开启互联网盲盒时代

近年来&#xff0c;盲盒经济在国内非常火爆&#xff0c;各类盲盒品牌层出不穷&#xff0c;深受国内外年轻人、消费者的喜爱。 目前&#xff0c;根据数据显示&#xff0c;盲盒市场不仅在线下异常火热&#xff0c;线上盲盒也是成为了大众的新选择。各类电商平台中盲盒的成交额更…