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

C++详解string(全面解析)

目录

string的概念: 

string的框架:

1、成员函数

 2、迭代器(Iterators)​编辑

 3、容量

4、元素访问

5、修改

6、非成员函数重载

string的构造和拷贝构造: 

 string的析构:

string的访问:

1、operator[]

2、iterator迭代器 

3、const_iterator

 4、反向迭代器

string的扩容机制

reserve函数

resize函数

string插入:

1、push_back

2、append

3、opeator+=

 4、replace

5、insert 

 6、erase

 7、replace

查找函数:

1、find()函数

 find_first_of函数​编辑

比较函数:

字符重载:


 

基于模板的出现,C++中就出现了各种模板类,而我们仅需要调用对应的模板类即可使用,十分的方便,今天我们来学习C++中第一个模板类——string

string的概念: 

 string类是一个字符顺序表。

string的框架:

1、成员函数

 2、迭代器(Iterators)

 3、容量

4、元素访问

5、修改

6、非成员函数重载

string的构造和拷贝构造: 

1、默认构造

2、拷贝构造

3、一部分拷贝构造(从pos位置开始,拷贝len长度,如果给的len超过当前位置后面到结尾的长度或者没有给len,那么就是从当前位置直接取到结尾)

npos:实际上是‘-1’,底层存的是补码,也就是42亿九千万,换句话说’-1‘代表不可能开出这么大的连续空间,所以npos代表取到字符串的结尾

4、字符串构造

5、字符串部分构造

6、用n个相同的字符’c'构造一个字符串

7、构造一个字符串的迭代器区间

#include<iostream>
#include<string>
using namespace std;
int main() {string s0("Hello world");string s1;string s2(s0);string s3(s2, 6, 5);string s4("Hello world Hello bit");string s5("Hello world Hello bit", 7);string s6(5, 'x');string s7(s0.begin(), s0.begin() + 6);cout << "s0:" << s0 << endl;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的析构:

一般自动调用,无需注意。

string的访问:

1、operator[]

 【】重载,在函数重载的那章见过,所以这里就不过多介绍,普通版本可读可写,const版本只读

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");//可读for (size_t i = 0; i < s1.size(); i++) {cout << s1[i] << " ";//等价于下面//cout << s4.operator[](i) << " ";}cout << endl;//可修改for (size_t i = 0; i < s1.size(); i++) {s1[i]++;}for (size_t i = 0; i < s1.size(); i++) {cout << s1[i] << " ";}cout << endl;return 0;
}

2、iterator迭代器 

类似于指针的作用,但不是真的指针。

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string::iterator it = s1.begin();while (it != s1.end()) {cout << *it << " ";it++;}cout << endl;return 0;
}

同样迭代器也可以进行修改。  

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string::iterator it = s1.begin();while (it != s1.end()) {*it -= 3;it++;}it = s1.begin();while (it != s1.end()) {cout << *it << " ";it++;}cout << endl;return 0;
}

那既然有下标+【】为什么还要弄一个iterator这么奇怪的东西,因为下标+【】这种形式只有string用起来方便,而iterator则可以适配多种类型。

而之前学习的范围for的底层也是iterator

3、const_iterator

#include<iostream>
#include<string>
using namespace std;
int main() {//普通string(可读可写)string s1("Hello world");//const_string(只读)const string s2("Hello world");//正常修改string::iterator it = s1.begin();while (it != s1.end()) {*it -= 3;it++;}//无法修改string::const_iterator it2 = s1.begin();while (it2 != s2.end()) {*it2 -= 3;it2++;}return 0;
}

 当用普通迭代器,可以看到我们可以正常修改,但const修饰后就无法进行修改了。

 4、反向迭代器

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string::reverse_iterator rit = s1.rbegin();while (rit != s1.rend()) {cout << *rit << " ";++rit;	}cout << endl;return 0;
}

 包括还有const_reverse_iterator,根据规律也能看出是什么意思,不再过多赘述,所以总共有四种迭代器:普通迭代器,const迭代器,反向迭代器,const反向迭代器

string的扩容机制

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");cout << s1.size() << endl;cout << s1.length() << endl;cout << s1.capacity() << endl;cout << s1.max_size() << endl;return 0;
}

#include<iostream>
#include<string>
using namespace std;
int main() {string s;size_t sz = s.capacity();cout << "capacity change: " << sz << endl;cout << "making s grow: \n";for (int i = 0 ; i < 100; i++) {s.push_back('c');if (sz != s.capacity()) {sz = s.capacity();cout << "capacity change: " << sz << '\n';}}return 0;
}

我们看运行结果,我用的是vs2022编译器,首先会进行2倍扩容,然后后面是1.5倍扩容,但是每个编译器可能结果不相同.

reserve函数

假如我们知道需要的大小,我们还可以进行手动扩容:

手动扩容可以一次达到需要的容量,而且vs2022编译器实际上还会多扩一点,这比让编译器自己一次一次的扩容要节省时间。而且只有大于capacity的时候才会进行扩容.

resize函数

也可以进行手动扩容,并且可以进行初始化。

#include<iostream>
#include<string>
using namespace std;
int main() {string s("Hello worldxxx");cout << s.size() << endl;cout << s.capacity() << endl << endl;s.resize(10);cout << s.size() << endl;cout << s.capacity() << endl << endl;s.resize(20);cout << s.size() << endl;cout << s.capacity() << endl << endl;s.resize(30);cout << s.size() << endl;cout << s.capacity() << endl << endl;return 0;
}

 

string插入:

1、push_back

作用:可以尾插一个字符,类似于数据结构

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");s1.push_back('x');cout << s1 << endl;return 0;
}

2、append

作用:可以在string后面追加字符串,而且有多种功能,例如:追加一个字符串的一部分,多个相同的字符等等,我们举一两个代码例子看一下。

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string s2("xxxxxx");//追加一个string类型的s2s1.append(s2);//追加一个字符串s1.append("aaaaaa");//追加多个字符s1.append(5, 'c');//追加一个字符串的一部分s1.append("yeahyeahyeah", 3, 6);//迭代器追加s1.append(s1.begin() + 2, s1.end());cout << s1 << endl;return 0;
}

3、opeator+=

作用:可以直接将string类型字符串、一般字符串、字符像赋值一样的+=在前一个string后,也是我们使用最频繁的,非常的好用。

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string s2("xxxxxx");s1 += s2;cout << s1 << endl;s1 += ("abcdef");cout << s1 << endl;s1 += ('c');cout << s1 << endl;return 0;
}

 4、replace

作用是:用新的字符串覆盖到原本的字符上。

格式:有上面的六种,最常用的就是前两个。

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string s2("This is a dog");//直接将s2替换给s1s1.assign(s2);cout << s1 << endl;//string& assign (const string& str, size_t subpos, size_t sublen);//从subpos位置开始,替换sublen个单位长度s1.assign(s2, 2, 5);cout << s1 << endl;return 0;
}

5、insert 

  作用:在某一个位置后面插入字符串。

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string s2(" This is a dog");s1.insert(5, s2);cout << s1 << endl;return 0;
}

 6、erase

作用:删除字符串的一部分,如果是erase()则直接删除整个字符串。 

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string s2(" This is a dog");s1.erase(2, 5);//删除整个字符串s2.erase();cout << s1 << endl;cout << s2 << endl;return 0;
}

 7、replace

作用:字符串的替换。 

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("Hello world");string s2(" This is a dog ");//将s2的字符串替换到s1字符串位置5,长度3的空间中s1.replace(5, 3, s2);cout << s1 << endl;cout << s2 << endl;return 0;
}

查找函数:

1、find()函数

作用:查找字符或字符串,找到返回下标,没找到返回npos

查找字符:

string s1("ababbbaa");cout << (s1.find('a')) << endl;//第二个参数为空,默认从0开始查找
cout << (s1.find('a',0)) << endl;//从0位置开始查找
cout << (s1.find('a',1)) << endl;//从1位置开始查找
cout << (s1.find('a',3)) << endl;//从3位置开始查找,前面的跳过
cout << (s1.find('c')) << endl;//未找到,返回4294967295,这是32位的-1,也是npos
cout << (s1.find('a',100)) << endl;//超出查找范围也是返回npos

查找字符串:

string s1("you are the apple of my eyes");
string s2("apple");cout << s1.find(s2) << endl;//查找s2
cout << s1.find("are", 2) << endl;//从位置2开始查找"are"
cout << s1.find("myself", 5, 2) << endl;//从位置5开始查找"myself"的前两个"my"

rfind函数和find差不多,只不过方向改变了,rfind是从后往前查找,大家可以参照find自行学习。 

 find_first_of函数

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("https://www.csdn.net/");size_t found = s1.find_first_of("aeiou");while (found != string::npos) {s1[found] = '*';found = s1.find_first_of("aeiou", found + 1);}cout << s1 << endl;return 0;
}

这里把s1里面的aeiou全部替换成*号。

find_last_of函数同find_first_of函数一样,只是查找方向不一样,也望大家自行学习。

比较函数:

字符重载:

#include<iostream>
#include<string>
using namespace std;
int main() {string s1("abdef");string s2("abcdef");//字符串比较规则,跟c一样,按照ASCII码大小,谁ASCII大谁就大cout << (s1 > s2) << endl;cout << (s1 < s2) << endl;return 0;
}

 返回值:bool类型,如果满足等式返回1,不满足返回0.

以上就是我对string的一些认识,如有问题望指正,感谢观看

相关文章:

  • 【虚拟化】KVM-virsh离线工具进行客户机虚拟机磁盘访问
  • 2024年CCPC网络赛 D题个人理解
  • AI绘画笔记
  • Eprime学习【E-basic语言、心理学实验程序设计】
  • 视频回放 | DolphinDB 2024 年度峰会主会场演讲精彩回顾
  • matplotlib画动态图
  • 【Unity踩坑】创建新项目后提示编译错误要进入安全模式
  • Linux - Linux安装部署Maven以及环境变量配置
  • 测试开发基础——测试用例的设计
  • 信创实践(3):基于x2openEuler将CentOS升级成openEuler,享受其带来的创新和安全特性
  • 解决 webpack 配置 sass-loader后报错,无法正常build
  • EasyExcel 学习之 导出 “类型及精度问题”
  • requests请求设置超时时间python
  • Debezium系列之:大规模应用debezium server采集数据库,从每个Debezium Server中导出JMX采集指标
  • 怎么利用接口发送图文彩信
  • php的引用
  • [译]如何构建服务器端web组件,为何要构建?
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • bootstrap创建登录注册页面
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • css选择器
  • exports和module.exports
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Sequelize 中文文档 v4 - Getting started - 入门
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 浅谈web中前端模板引擎的使用
  • 让你的分享飞起来——极光推出社会化分享组件
  • 我的面试准备过程--容器(更新中)
  • 智能网联汽车信息安全
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • # 职场生活之道:善于团结
  • #Linux(Source Insight安装及工程建立)
  • #数据结构 笔记三
  • (1)SpringCloud 整合Python
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (c语言)strcpy函数用法
  • (C语言)共用体union的用法举例
  • (web自动化测试+python)1
  • (不用互三)AI绘画工具应该如何选择
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (十五)使用Nexus创建Maven私服
  • (微服务实战)预付卡平台支付交易系统卡充值业务流程设计
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)jQuery 基础
  • (转)项目管理杂谈-我所期望的新人
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .net 受管制代码
  • .NET多线程执行函数
  • .Net各种迷惑命名解释
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .NET是什么
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [ C++ ] 类和对象( 下 )
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798