Cpp知识点系列-字符串

news/2024/5/21 11:02:11/文章来源:https://blog.csdn.net/qq_41461536/article/details/128112344

前言

记录一些对字符串的理解。

接下来我所说的都是依赖于头文件<string>的。

理论

什么是字符串

字符串实际上是使用 null 字符 '\0' 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

string与cstring有什么区别

<string>是C++标准库头文件,包含了拟容器class std::string的声明(不过class string事实上只是basic_string<char>typedef),用于字符串操作。

<cstring>是C标准库头文件<string.h>的C++标准库版本,包含了C风格字符串(NULL即'\0'结尾字符串)相关的一些类型和函数的声明,例如strcmp、strchr、strstr等。

两者最大区别在于:

  • string是新标准,定义了namespace std;cstring定义中包含的是string.h

  • string中可以进行+ = += >等运算,而cstring中不能进行相关运算。

什么是string类型的迭代器

声明一个string类中特有的类型size_type变量,名称为position

string::size_type position;

迭代器是一个变量,相当于容器和操纵容器的算法之间的中介 , 实在理解困难认为是个特别的int下标也可以。

迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。

//从类名获取该对象
string::npos;//从对象获取该对象
string tempstr;
tempstr.npos;

这个npos是个特别的迭代器对象,可以理解成为string类型中特别的NULL,如果查找失败或者遍历完毕之后迭代器的值就是这个.

操作

首先引入头文件,并且在命名空间中使用。

#include<string>
using namespace std;

Strings常用方法

方法名作用
Operators操作符,可以用 ==, >, <, >=, <=, and !=比较字符串. 可以用 + 或者 += 操作符连接两个字符串, 并且可以用[]获取特定的字符
append()在字符串的末尾添加文本(就是+=)
compare()比较两个字符串
empty()如果字符串为空,返回真
erase()删除字符
insert()插入字符
length()返回字符串的长度
replace()替换字符
size()返回字符串中字符的数量(结果等价于length)
substr()返回某个子字符串
swap()交换两个字符串的内容

如果可以使用自带的方法去实现的话自然是比较好的,但是如果只能够针对部分字符进行复杂变化的话,就需要转化成为char*类型的数组

构造法

平常更多是用等号直接赋值,如果要求字符串中间有结尾符可以这样声明。

void stringTestConstruct() {string str =string("12345 \0 54321", 13);//不等价于str="12345 \0 54321";cout << str<<endl;string str1 = "12345 \0 54321";cout << str1;
}

image-20221108134445583

image-20221108132722476

append

void stringTestAppend() {string str = "Hello";str.append(3, '!');//等价于str+="!!!" ;cout << str;
}

image-20201126161713323

初学时,没考虑太多,后来才发现在添加'\0'字符时有奇效。

void stringTestAppend2() {string str="abc";str.append("\0 def",5);//等价于 str =string("abc\0 def", 8);cout << str;
}

image-20221108135309114

compare

compare()比较时逐字符比较的,一旦能比较出结果,就不再比较了。

虽然有多个重载,但是只需要理解,在this字符串与传入的比较字符串str一部分(至于是哪一部分用起点和长度来评定)之间进行的比较即可。

 int compare( const basic_string &str );int compare( const char *str );int compare( size_type index, size_type length, const basic_string &str );int compare( size_type index, size_type length, const basic_string &str, size_type index2,size_type length2 );int compare( size_type index, size_type length, const char *str, size_type length2 );

在str之前的参数是修饰this,在str之后的参数是修饰str的

返回值情况
小于零this < str(自己弱小就认''负'')
this == str
大于零this > str(自己强大就嚣''正'')
void stringTestCompare() {string s1 = "abandon";string s2 = "about";int b = s1.compare(s2);//直接比较,s1小于s2,故返回-1int c = s1.compare(2, 4, s2);//s1下标为2的字符a开始的4个字符ando和s2进行比较。ando大于s2故返回1cout << c << endl;int d = s1.compare(2, 4, s2, 1, 3);cout << d << endl;//s1下标为2的字符a开始的4个字符ando和s2下标为1的字符b开始的3个字符bou比较。前者小,故返回-1。string s3 = "abc";string s4 = "abc";int e = s3.compare(s4);//相等返回0cout << e << endl;
}

erase

也有参数为迭代器的函数,在下面介绍。

basic_string &erase( size_type index = 0, size_type num = npos );
  • 删除从index索引开始的num个字符, 返回删减后的字符串。其中index默认从0开始,num默认是最大值。

void stringTestErase() {string s("1234567890123456789012345");//总共25个字符cout << s << endl;cout << s.erase(10, 6) << endl;//从下标第10的字符开始删除,一共删除6个。cout << s.erase(10) << endl;//删除下标为10的字符及之后的 ==保留下标小于10的字符cout << s.erase();//清空字符串
}

image-20201126200020627

insert

basic_string &insert( size_type index, const basic_string &str );basic_string &insert( size_type index, const char *str );basic_string &insert( size_type index1, const basic_string &str, size_type index2, size_type num);basic_string &insert( size_type index, const char *str, size_type num );basic_string &insert( size_type index, size_type num, char ch );
  • 在字符串的位置index插入字符串str;

  • 在字符串的位置index插入字符串str的子串(从index2开始,长num个字符);

  • 在字符串的位置index插入字符串str的num个字符;

  • 在字符串的位置index插入num个字符ch的拷贝字符串。

其实理解起来就是,在本字符串的index位置,插入参数中的字符串的一部分(至于是哪一部分

用起点和长度来评定)。

void stringTestInsert() {string str = "abc";str.insert(1, "123");/*在下标为1的位置,插入字符串123全部*/cout << str << endl;str = "abc";str.insert(1, "123", 1, 1);/*在下标为1的位置,插入字符串123的一部分,并且从下标1开始,长度为1的一段*/cout << str << endl;str = "abc";str.insert(1, "123", 2);/*在下标为1的位置,插入字符串123的一部分,并且从下标0开始,长度为2的一段*/cout << str << endl;str = "abc";str.insert(1, 2, 'z');/*在下标为1的位置,插入2个字符z*/cout << str;
}

image-20221108141757159

length

其实不用纠结在获取长度的时候是用size还是length,至少在GCC6的情况下,返回的都是同一个字段_M_string_length

void stringTestLength() {//其实后面都是返回的同一个字段_M_string_length。string s("1234567890123456789012345");//总共25个字符cout << s.size()  << endl;//输出25cout << s.length()  << endl;//输出25
}

replace

basic_string &replace( size_type index, size_type num, const basic_string &str );
basic_string &replace( size_type index1, size_type num1, const basic_string &str, size_type index2,size_type num2 );
basic_string &replace( size_type index, size_type num, const char *str );
basic_string &replace( size_type index, size_type num1, const char *str, size_type num2);
basic_string &replace( size_type index, size_type num1, size_type num2, char ch );

其实理解起来就是,在将本字符串的index位置长度为num的字符串,替换成参数中的字符串的一部分(至于是哪一部分用起点和长度来评定)。

一般用起来的时候,更多是和find函数一起,实现查找替换的作用。然而find函数是涉及到了迭代器,所以这里只是简单示例一下。有兴趣可以直接下翻。

void stringTestReplace() {string str="1234567890";str.replace(0,9,"ABC");/*把下标从0开始、长度为2的一段字符串,替换为ABC*/cout << str<<endl;str="1234567890";str.replace(str.find('8'),3,"ABC");/*把从字符8开始、长度为2的一段字符串,替换为ABC*/cout << str;
}

substr

  basic_string substr( size_type index, size_type num = npos ); 

截取本字符串从index开始之后的num个字符,没错就是跟上面的删除差不多!

特别的,用程序形象的看一眼效果:

void stringTestSubstr() {string s("123456789012345678901234567890");cout << s << endl;printf("%30s\n", s.substr(21).c_str());cout << s.erase(21) << endl;
}

image-20201126222643653

swap

 void swap( basic_string &str );

这个函数的作用主要就是将两个字符串的全部元素进行交换。

void stringTestSwap() {string first( "This comes first" );string second( "And this is second" );first.swap( second );cout << first << endl;cout << second << endl;
}

image-20201126222955616

如果只是针对部分元素,可以用insertreplace进行操作。

转char*

方法名作用
c_str()将字符串以C字符数组的形式返回
copy(*str, num, index )将内容复制为一个字符数组
data()返回内容的字符数组形式

c_str( )

 const char *c_str();

返回一个const临时指针,指向以\0结尾的字符数组,应该使用strcpy()函数等来操作。

void stringTestC_str() {//数组char c[20];string s="1234";strcpy(c,s.c_str());//注意strcpy函数是在cstring头文件中的cout<<c;//指针string str = "hello";const char* p1 = str.c_str();//加constchar * p2=(char*)str.c_str();//或者是强制转换
}

data( )

const char *data();

照常来说是字符串内容外,**不附加结束字符'\0'**。

有资料显示,两者是应该有区别的c_str()有结束符,而data()没有结束符。

image-20201126172130028

因为我这个编译环境的问题,在dev的环境中两个方法,其实都是返回的_M_data()方法而已的。

copy(*str,num,index )

拷贝自己的num个字符到str中(从索引index开始)。返回值是拷贝的字符个数

size_type copy( char *str, size_type num, size_type index );

由于还需要手动加结束符

void stringTestCopy() {string str = "hmmm";char p[10];str.copy(p, 3, 0);/*把从0开始、长度为3的字符串,复制到字符数组p之中*/p[3] = '\0';//注意手动加结束符!!!cout << p;
}

迭代器

方法名作用
begin()返回一个迭代器,指向第一个字符
end()返回一个迭代器,指向字符串的末尾。(最后一个字符的下一个位置)
erase()删除字符
find()在字符串中查找字符
find_first_of()查找第一个与value中的某值相等的字符
find_first_not_of()查找第一个与value中的所有值都不相等的字符
find_last_of()查找最后一个与value中的某值相等的字符
find_last_not_of()查找最后一个与value中的所有值都不相等的字符
get_allocator()返回配置器
insert()插入字符
rbegin()返回一个逆向迭代器,指向最后一个字符
rend()返回一个逆向迭代器,指向第一个元素的前一个位置
replace()替换字符
rfind()查找最后一个与value相等的字符(逆向查找)

find

把str的全部字符当作整体进行查找.

 size_type find( const basic_string &str, size_type index );size_type find( const char *str, size_type index );size_type find( const char *str, size_type index, size_type length );size_type find( char ch, size_type index );
  • 返回str在字符串中第一次出现的位置(从index开始查找)如果没找到则返回string::npos

  • 返回str在字符串中第一次出现的位置(从index开始查找,长度为length)。如果没找到就返回string::npos

  • 返回字符ch在字符串中第一次出现的位置(从index开始查找)。如果没找到就返回string::npos

代码:

void stringIteratorTestFind() {string s("qwe123qwee123qweqwe1");string flag = "123";string::size_type position = 0;int i = 1;while ((position = s.find(flag, position)) != string::npos) {cout << "position  " << i << " : " << position << endl;position++;i++;}
}

image-20201126230709115

find_first_of

 size_type find_first_of( const basic_string &str, size_type index = 0 );size_type find_first_of( const char *str, size_type index = 0 );size_type find_first_of( const char *str, size_type index, size_type num );size_type find_first_of( char ch, size_type index = 0 );

跟上面的参数相似,重点理解find的即可。

特别注意

find_first_of 函数和find函数最大的区别就是,如果在str1中查找str2时,如果str1中含有str2中的任何字符,就会查找成功,而find则只有全部相同才会查找成功.

比如:

void stringIteratorTestFind_first_of () {string s("qwe123qwee123qweqwe1");string flag="123";string::size_type position=0;int i=1;while((position=s.find_first_of(flag,position))!=string::npos) {cout<<"第"<<i<<"次匹配 : "<<position<<endl;position++;i++;}
}

与上面的例子区别只是更换了一个函数而已,但是结果完全不同。

image-20221108150441682

至于其他的not,last的变名函数则是顾名思义即可。

rfind

反向查找子字符串

 size_type rfind( const basic_string &str, size_type index );size_type rfind( const char *str, size_type index );size_type rfind( const char *str, size_type index, size_type num );size_type rfind( char ch, size_type index );

当正向查找与反向查找得到的位置不相同说明子串不唯一。

erase

 iterator erase( iterator pos );iterator erase( iterator start, iterator end );
  • 删除pos指向的字符, 返回指向下一个字符的迭代器,

  • 删除从start到end的所有字符, 返回一个迭代器,指向被删除的最后一个字符的下一个位置

insert

 iterator insert( iterator i, const char &ch );void insert( iterator i, size_type num, const char &ch );void insert( iterator i, iterator start, iterator end );
  • 在迭代器i表示的位置前面插入一个字符ch,

  • 在迭代器i表示的位置前面插入num个字符ch的拷贝,

  • 在迭代器i表示的位置前面插入一段字符,从start开始,以end结束.

replace

 basic_string &replace( iterator start, iterator end, const basic_string &str );basic_string &replace( iterator start, iterator end, const char *str );basic_string &replace( iterator start, iterator end, const char *str, size_type num );basic_string &replace( iterator start, iterator end, size_type num, char ch );
  • 用str中的字符替换本字符串中的字符,迭代器start和end指示范围

  • 用str中的num个字符替换本字符串中的内容,迭代器start和end指示范围,

  • 用num个ch字符替换本字符串中的内容,迭代器start和end指示范围.

Strings全部方法

方法名作用
Constructors构造函数,用于字符串初始化
Operators操作符,用于字符串比较和赋值
append()在字符串的末尾添加文本
assign()为字符串赋新值
at()按给定索引值返回字符
begin()返回一个迭代器,指向第一个字符
c_str()将字符串以C字符数组的形式返回
capacity()返回重新分配空间前的字符容量
compare()比较两个字符串
copy()将内容复制为一个字符数组
data()返回内容的字符数组形式
empty()如果字符串为空,返回真
end()返回一个迭代器,指向字符串的末尾。(最后一个字符的下一个位置)
erase()删除字符
find()在字符串中查找字符
find_first_of()查找第一个与value中的某值相等的字符
find_first_not_of()查找第一个与value中的所有值都不相等的字符
find_last_of()查找最后一个与value中的某值相等的字符
find_last_not_of()查找最后一个与value中的所有值都不相等的字符
get_allocator()返回配置器
insert()插入字符
length()返回字符串的长度
max_size()返回字符的最大可能个数
rbegin()返回一个逆向迭代器,指向最后一个字符
rend()返回一个逆向迭代器,指向第一个元素的前一个位置
replace()替换字符
reserve()保留一定容量以容纳字符串(设置capacity值)
resize()重新设置字符串的大小
rfind()查找最后一个与value相等的字符(逆向查找)
size()返回字符串中字符的数量
substr()返回某个子字符串
swap()交换两个字符串的内容

感谢

参考书籍《C++语言程序设计(第4版)》(郑莉,董渊)

C++string的compare()比较函数

感谢现在的好奇,为了能成为更好的自己。

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

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

相关文章

Linux多线程C++版(七) 线程互斥方式-----读写锁

目录1.读写锁基本概念2.读写锁创建和销毁3.读写锁的加锁和解锁4.代码了解读写锁5.线程互斥案例---ATM取钱--使用读写锁1.读写锁基本概念 线程使用互斥锁缺乏读并发性当读操作比较多&#xff0c;写操作比较少时&#xff0c;可使用读写锁提高线程读并发性读写锁数据类型 pthread…

专访D-Wave CEO:量子计算的过去、现在和未来

&#xff08;图片来源&#xff1a;网络&#xff09; 量子计算可能成为一项颠覆性技术&#xff1a;它建立在听起来非常奇特的物理学基础上&#xff0c;并有望以前所未有的速度和效率解决某些类别的问题。一些人认为&#xff0c;目前在量子计算领域的承诺太多&#xff0c;交付却不…

FPGA书籍

1、Xilinx FPGA 权威设计指南 本书系统地介绍了Xilinx新一代集成开发环境Vivado 2018的设计方法、设计流程和具体实现。 全书共11章&#xff0c;内容包括Xilinx新一代UltraScale结构、Vivado集成设计环境导论、Vivado工程模式基本设计实现、Vivado非工程模式基本设计实现、创建…

Linux centos7.6 安装elasticsearch8.x (es8) 教程

系列-Linux centos7.6 安装elasticsearch8.x (es8) 教程 Linux centos7.6 安装elasticsearch8.x (es8) 教程_言之有李LAX的博客-CSDN博客 系列-linux安装elasticsearch-head &#xff08;es可视化界面&#xff09; linux安装elasticsearch-head &#xff08;es可视化界面&am…

Elasticsearch倒排索引

什么是正排索引&#xff1f; 如下图&#xff0c;有一张商品表&#xff08;tb_goods&#xff09;&#xff1a; 对于mysql数据库来说&#xff0c;肯定会给“id”创建主键索引&#xff0c;然后根据“id”来查询对应的商品信息&#xff0c;而这种情况就被称为“正排索引” 现在有…

吴恩达2022机器学习——第二部分高级学习算法第三周笔记

目录1.1决定下一步做什么&#xff08;构建机器学习的实用建议&#xff09;1.2模型评估1.3模型选择&交叉验证测试集的训练方法模型选择总结举例2.1通过偏差与方法进行诊断2.2正则化、偏差、方差1.1决定下一步做什么&#xff08;构建机器学习的实用建议&#xff09; 从一个例…

[附源码]计算机毕业设计springboot健身房信息管理

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

传统制造企业进行数字化转型,是翻身还是翻船?

数实融合正在从可选项&#xff0c;变成每个行业都要面对的必选项&#xff0c;制造企业也从野蛮生长逐渐步入有序的数字化世界。 出品|产业家 2022年&#xff0c;疫情及经济环境全面淬炼了各行各业&#xff0c;大多数能有效应用数字化持续经营的企业成为幸存者&#xff0c;数字…

Microolap DAC for MySQL驱动程序或其他库

Microolap DAC for MySQL驱动程序或其他库 用于MySQL和Delphi/CBuilder(也称为MySQLDAC)的Microolap直接访问组件是一组Borland Delphi/CBuilder组件&#xff0c;允许直接连接到MySQL数据库服务器。DAC for MySQL允许您创建Delphi/CBuilder应用程序&#xff0c;无需BDE、ODBC或…

Caffeine 源码、架构、原理(史上最全,10W超级字长文)

文章很长&#xff0c;而且持续更新&#xff0c;建议收藏起来&#xff0c;慢慢读&#xff01;疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 &#xff1a; 免费赠送 :《尼恩Java面试宝典》 持续更新 史上最全 面试必备 2000页 面试必备 大厂必备 涨薪必备 免费赠送 经典…

NHS-PEG-Biotin,Biotin-PEG-NHS,活性酯peg生物素生物素PEG衍生物

Biotin-PEG-NHS&#xff08;NHS-PEG-Biotin&#xff09;是生物素PEG衍生物的一种&#xff0c;该化学试剂其中文名为活性酯-聚乙二醇-生物素&#xff0c;它所属分类为Biotin PEG NHS ester PEG。 peg试剂的分子量均可定制&#xff0c;有&#xff1a;活性酯-聚乙二醇2-生物素&am…

记录--用JS轻松实现一个录音、录像、录屏的工具库

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 最近项目遇到一个要在网页上录音的需求&#xff0c;在一波搜索后&#xff0c;发现了 react-media-recorder 这个库。今天就跟大家一起研究一下这个库的源码吧&#xff0c;从 0 到 1 来实现一个 R…

QCSPCChart for Java R3x0 Crack

Java 的 SPC 控制图工具 版本 3.04 QCSPCChart添加变量控制图&#xff08;X-Bar R、X-Bar Sigma、Individual Range、Median Range、EWMA、MA、MAMR、MAMS 和 CuSum 图&#xff09;、属性控制图&#xff08;p-、np-、c-、u- 和DPMO 图&#xff09;、频率直方图和 Pareto 图到…

HotSpot VM垃圾收集器——Serial Parallel CMS G1垃圾收集器的JVM参数、使用说明、GC分析

目录HotspotVM的垃圾收集器简介1. Serial Collector2. Parallel Collector&#xff08;throughput collector&#xff09;3. Concurrent Mark Sweep Collector&#xff08;CMS&#xff09;4. Garbage-First Garbage Collector&#xff08;G1&#xff09;5. Z Garbage Collector…

PHP表单处理的案例分析

目录 知识补充 实现过程 前端代码 后端代码 简单分析 知识补充 表单简介&#xff08;来自Mr._Dang&#xff09; action&#xff1a;提交的地址 method&#xff1a;提交的方式 get&#xff1a; 参数是在url中的&#xff0c;不安全&#xff0c;传输量比较少&#xff…

【JSP】EL表达式

EL表达式EL表达式干什么用的&#xff1f;EL表达式的使用面试题如何输出对象属性值&#xff1f;域中取数据注意事项EL表达式的空处理如何从Map集合中取数据如何从数组或者List集合中获取数据局部忽略EL表达式EL表达式的内置对象EL表达式的运算符EL表达式干什么用的&#xff1f; …

BL200EC如何与欧姆龙相连

1、欧姆龙 NX1P2 的 Port1 接到电脑的网口&#xff0c;Port2 接到 BL200EC 的 ETH1 网口。 欧姆龙 NX1P2 和 BL200EC 通电。 2、打开 Sysmac Studio 软件&#xff0c;新建工程&#xff0c;选择 NX1P2-9024DT&#xff0c;点击创建。 ​ 编辑切换为居中 添加图片注释&#xf…

玩机搞机---卸载内置软件 无root权限卸载不需要的软件 安全卸载

目前的机型出厂都会自带一些内置软件。个别的还无法删除。各种弹窗广告 等等占用系统资源。操作卡顿。而很多卸载软件有需要root权限才可以运行。那么有没有方法可以无需root就可以卸载内置软件呢。答案是有的。而且方法很多。今天的帖子就列举一下常用的操作步骤 操作前了解的…

Matlab最小二乘平面拟合(SVD方法)—点云处理及可视化第3期

在之前的文章中&#xff0c;分享了Matlab基于PCA的平面拟合方法&#xff1a; 这一次&#xff0c;再来分享一下基于奇异值分解&#xff08;Singular Value Decomposition, SVD&#xff09;的平面拟合。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;《Matlab点云处理及…

极空间Docker安装Alist套件整合阿里云盘、百度云盘等网盘资源并挂载到本地供极影视刮削播放完整教程

文章目录0、前言1、在docker中安装alist套件1.1、拉取并下载alist镜像1.2.安装alist镜像2、访问并设置alist2.1、访问alist2.2、配置alist2.2.1、在alist中添加阿里云盘2.2.2、在alist中添加其它网盘3、在极空间中将前述网盘挂载到本地4、在极影视中扫描刮削挂载到本地的云盘中…