C++primer第九章 顺序容器 9.5 额外的string操作

  • 除了顺序容器共同的操作之外,string类型还提供了一些额外的操作。这些操作中 的大部分要么是提供string类和C 风格字符数组之间的相互转换,要么是增加了允许我们用下标代替迭代器的版本。
  • 标准库string类型定义了大量函数。幸运的是,这些函数使用了重复的模式。由于 函数过多,本节初次阅读可能令人心烦,因此读者可能希望快速浏览本节。当你了解
    string支持哪些类型的操作后,就可以在需要使用一个特定操作时回过头来仔细阅读

9 .5 .1 构造string的其他方法

  • 除了我们在3.2.1节 (第76页)已经介绍过的构造函数,以及与其他顺序容器相同的构造函数(参见表9.3,第299页)外,string类型还支持另外三个构造函数,如表9.11 所示。

  • 这些构造函数接受一个string或一个const char*参数,还接受(可选的)指定拷贝多少个字符的参数。当我们传递给它们的是一个string时,还可以给定一个下标来指出从哪里开始拷贝:
const char *cp = "Hello World!!!"; //以空字符串结束的数组
char noNull[] = {'H','i'}; // 不是以空的字符串结束
string s1(cp); //拷贝cp中的字符直到遇到空的字符串 ,因此 s1 == "Hello World!!!"
string s2(noNull,2); //拷贝两个字符串 s2 == "Hi"
string s3(noNull);//未定义 noNull不以空字符结束
string s4(cp + 6,5);//从cp[6]开始拷贝5个字符 s4 == "Word" 
string s5(sl,6,5);//从s1[6]开始拷贝5个字符 s5 == "Word" 
string s6(s1,6);//从s1[6]开始拷贝直至末尾 s6 == "Word" 
string s7(s1,6,20);//从s1[6]开始拷贝直至末尾 s7 == "Word" 
string s8(s1,16);//抛出一个out_of_range的异常
  • 通常当我们从一个const char*创建string时,指针指向的数组必须以空字符结 尾,拷贝操作遇到空字符时停止。如果我们还传递给构造函数一个计数值,数组就不必以空字符结尾。如果我们未传递计数值且数组也未以空字符结尾,或者给定计数值大于数组大小,则构造函数的行为是未定义的。
  • 当从一个string拷贝字符时,我们可以提供一个可选的开始位置和一个计数值。开始位置必须小于或等于给定的string的大小。如果位置大于size,则构造函数抛出一 个 out_of_range异常 (参见5.6节,第 173页)。如果我们传递了一个计数值,则从给定位置开始拷贝这么多个字符。不管我们要求拷贝多少个字符,标准库最多拷贝到string 结尾,不会更多。

substr操作

  • substr操作 (参见表9.12) 返回一个string,它是原始string的一部分或全部的拷贝。可以传递给substr 一个可选的开始位置和计数值

  • 如果开始位置超过了 string的大小,则 substr函数抛出一个out_of_range异常(参 见 5.6节,第 173页)。如果开始位置加上计数值大于string的大小,则 substr会调 整计数值,只拷贝到string的末尾。

9.5.2改变string的其他方法

  • string类型支持顺序容器的赋值运算符以及assign、insert和erase操作(参见9.2.5节,第302页;9.3.1节,第306页;9.3.3节,第311页)。除此之外,它还定义了额外的insert和erase版本。除了接受迭代器的insert和erase版本外,string还提供了接受下标的版本。下标指出了开始删除的位置,或是insert到给定值之前的位置:
  • s.insert(s.size(),5,'!');//在s末尾插入5个感叹号
  • s.erase(s.size()-5,5);//从s删除最后5个字符
  • 标准库string类型还提供了接受C风格字符数组的insert和assign版本。例如,我们可以将以空字符结尾的字符数组insert到或assign给一个string:
  • const char*cp="Stately,plumpBuck";
  • s.assign(cp,7);//s=="Statelyn"
  • s.insert(s.size(),cp+7);//s=="Stately,plumpBuck”
  • 此处我们首先通过调用assign替换s的内容。我们赋予s的是从cp指向的地址开始的7个字符。要求赋值的字符数必须小于或等于cp指向的数组中的字符数(不包括结尾的空字符)。
  • 接下来在s上调用insert,我们的意图是将字符插入到s[size()]处(不存在的)元素之前的位置。在此例中,我们将cp开始的7个字符(至多到结尾空字符之前)拷贝到s中。
  • 我们也可以指定将来自其他string或子字符串的字符插入到当前string中或赋予当前string:
  • strings="some string",s2=nsome other string";s.insert(0,s2);//在s中位置0之前插入s2的拷贝
  • //在s[0]之前插入s2中s2[0]开始的s2.size()个字符
  • s.insert(0,s2,0,s2.size());

append和replace函数

  • string类定义了两个额外的成员函数:append和replace,这两个函数可以改变string的内容。表9.13描述了这两个函数的功能。append操作是在string末尾进行插入操作的一种简写形式
  • strings("C++Primer"),s2=s;//将s和s2初始化为"C++Primer*'
  • s.insert(s.size(),"4thEd");//s=="C++Primer 4th Ed.
  • s2.append("4thEd");//等价方法:将"4thEd."追加到s2;  s==s2
  • replace操作是调用erase和insert的一种简写形式:
  • //将“4th”替换为"5th"的等价方法
  • s.erase(11,3);//s=="C++Primer Ed."
  • s.insert(11,"5th");//s=="C++ Primer 5th Ed.”
  • //从位置11开始,删除3个字符并插入5th
  • s2.replace(11,3,"5th");//等价方法:s==s2
  • 此例中调用replace时,插入的文本恰好与删除的文本一样长。这不是必须的,可以插入一个更长或更短的string:
  • s.replace(11,3,'Fifth');//s=="C++Primer Fifth Ed    在此调用中,删除了3个字符,但在其位置插入了5个新字符

改变string的多种重载函数

  • 表9.13列出的append、assign,insert和replace函数有多个重载版本。根据我们如何指定要添加的字符和string中被替换的部分,这些函数的参数有不同版本。幸运的是,这些函数有共同的接口。
  • assign和append函数无须指定要替换string中哪个部分:assign总是替换string中的所有内容,append总是将新字符追加到string末尾。replace函数提供了两种指定删除元素范围的方式。可以通过一个位置和一个长度来指定范围,也可以通过一个迭代器范围来指定。insert函数允许我们用两种方式指定插入点:用一个下标或一个迭代器。在两种情况下,新元素都会插入到给定下标(或迭代器)之前的位置。
  • 可以用好几种方式来指定要添加到string中的字符。新字符可以来自于另一个string,来自于一个字符指针(指向的字符数组),来自于一个花括号包围的字符列表,或者是一个字符和一个计数值。当字符来自于一个string或一个字符指针时,我们可以传递一个额外的参数来控制是拷贝部分还是全部字符。
  • 并不是每个函数都支持所有形式的参数。例如,insert就不支持下标和初始化列表参数。类似的,如果我们希望用迭代器指定插入点,就不能用字符指针指定新字符的来源。

9.5.3string搜索操作

  • string类提供了6个不同的搜索函数,每个函数都有4个重载版本。表9.14描述了这些搜索成员函数及其参数。每个搜索操作都返回一个string::size_type值,表示匹配发生位置的下标。如果搜索失败,则返回一个名为string::npos的static成员(参见7.6节,第268页)。标准库将npos定义为一个conststring::size_type类型,并初始化为值-1。由于npos是一个unsigned类型,此初始值意味着npos等于任何string最大的可能大小(参见2.1.2节,第32页)。
  • find函数完成最简单的搜索。它查找参数指定的字符串,若找到,则返回第一个匹配位置的下标,否则返回npos:
  • string name("AnnaBelle");
  • auto posl=name.find("Annan");//posl==0
  • 这段程序返回0,即子字符串"Anna"在"AnnaBelle”中第一次出现的下标。搜索(以及其他string操作)是大小写敏感的。当在string中查找子字符串时,要注意大小写:
  • string lowercase("annabelle**);
  • posl=lowercase.find("Anna");//posl==npos
  • 这段代码会将posl置为npos,因为Anna与anna不匹配。
  • 一个更复杂一些的问题是查找与给定字符串中任何一个字符匹配的位置。例如,下面代码定位name中的第一个数字:
  • string numbers("0123456789n"),name("r2d2"); 
  • autopos=name.find_first_of(numbers);//返回1,即,name中第一个数字的下标
  • 如果是要搜索第一个不在参数中的字符,我们应该调用find_first_not_of。例如,为了搜索一个string中第一个非数字字符,可以这样做:
  • string dept("03714p3");
  • autopos=dept.find_first_not_of(numbers);  //返回5--字符,p,的下标

指定在哪里开始搜索

  • 我们可以传递给find操作一个可选的开始位置。这个可选的参数指出从哪个位置开 始进行搜索。默认情况下,此位置被置为0。一种常见的程序设计模式是用这个可选参数在字符串中循环地搜索子字符串出现的所有位置:
string::size_type pos = 0;
//每步循环查找name中的一个数
while((pos = name.find_first_of(numbers,pos))//numbers表示我们要找到的是数字!= string::npos)//npos是指string的末尾最后的位置,一般是std::container::size_typestd::cout << "found number at index" << pos << "element is "<< name[pos] << endl;++pos;//移动到下一个字符
} 
  • while的循环条件将pos重置为从pos开始遇到的第一个数字的下标。只要 find_first_of返回一个合法下标,我们就打印当前结果并递增pos。 如果我们忽略了递增pos,循环就永远也不会终止。为了搞清楚原因,考虑如果不做递增运算会发生什么。在第二步循环中,我们从pos指向的字符开始搜索。这个字符是—个数字,因此find_first_of会 (重 复 地 )返 回 pos!

逆向搜索

  • 到现在为止,我们已经用过的find操作都是由左至右搜索。标准库还提供了类似的, 但由右至左搜索的操作。rfind成员函数搜索最后一个匹配,即子字符串最靠右的出现位置:
  • string river("Mississippi");
  • auto first_pos = river. find ("is") ; // 返回 1
  • auto last_pos = river. rfind (nisn) ; // 返回 4
  • find返回下标1,表示第一个"is”的位置,而 rfind返回下标4,表示最后一个"is”的位置。
  • 类似的,find_last函数的功能与find_first函数相似,只是它们返回最后一个而不是第一个匹配:
  • find_last_of搜索与给定string中任何一个字符匹配的最后一个字符。
  • find_last_not_of搜索最后一个不出现在给定string中的字符。
  • 每个操作都接受一个可选的第二参数,可用来指出从什么位置开始搜索。

9.5.4compare函数

  • 除了关系运算符外(参见3.2.2节,第79页),标准库string类型还提供了一组compare函数,这些函数与C标准库的strcmp函数(参见3.5.4节,第109页)很相似。类似strcmp,根据s是等于、大于还是小于参数指定的字符串,s.compare返回0、正数或负数。
  • 如表9.15所示,compare有6个版本。根据我们是要比较两个string还是一个string与一个字符数组,参数各有不同。在这两种情况下,都可以比较整个或一部分字符串

9.5.5数值转换

  • 字符串中常常包含表示数值的字符。例如,我们用两个字符的string表示数值15一字符1,后跟字符5。--般情况,一个数的字符表示不同于其数值。数值15如果保存为16位的short类型,则其二进制位模式为0000000000001111,而字符串"15"存为两个Latin-1编码的char,二进制位模式为0011000100110101。第一个字节表示字符1,其八进制值为061,第二个字节表示字符5,,其Latin-1编码为八进制值065。
  • 新标准引入了多个函数,可以实现数值数据与标准库string之间的转换:
  • int i=42;string s=to_string(i);//将整数i转换为字符表示形式
  • doubled=stod(s);//将字符串s转换为浮点数
  • 此例中我们调用to_string将42转换为其对应的string表示,然后调用stod将此string转换为浮点值
  • 要转换为数值的string中第一个非空白符必须是数值中可能出现的字符:
  • string s2=“pi=3.14”;
  • //转换s中以数字开始的第一个子串,结果d=3.14
  • d=stod(s2.substr(s2.find_first_of(*'+-.0123456789*')));
    在这个stod调用中,我们调用了find_first_of(参见9.5.3节,第325页)来获得s中第一个可能是数值的一部分的字符的位置。我们将S中从此位置开始的子串传递给
    stodostod函数读取此参数,处理其中的字符,直至遇到不可能是数值的一部分的字符。然后它就将找到的这个数值的字符串表示形式转换为对应的双精度浮点值。
  • string参数中第一个非空白符必须是符号(+或-)或数字。它可以以Ox或0X开头来表示十六进制数。对那些将字符串转换为浮点值的函数,string参数也可以以小数点(.)开头,并可以包含e或E来表示指数部分。对于那些将字符串转换为整型值的函数,根据基数不同,string参数可以包含字母字符,对应大于数字9的数。

 

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

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

相关文章

Zookeeper Mac下安装操作

目录一、下载Zookeeper二、修改配置1、设置启动配置文件2、修改配置三、启动Zookeeper服务命令1、bin目录下执行&#xff08;1&#xff09;启动Zookeeper命令&#xff08;2&#xff09;查看Zookeeper状态命令&#xff08;3&#xff09;停止Zookeeper命令2、配置环境变量执行&am…

2014年考研英语二作文PartB图表题

作文详细解析 题目 Write an essay based on the following chart, in which you should interpret the chart, and give your comments You should write about 150 words on the ANSWER SHEET.(15 points) 注意点 1.图表题在第一段描述图表信息时,一定要写清楚y轴变化…

C++primer第九章 顺序容器 9.6 容器适配器

9.6容器适配器 除了顺序容器外&#xff0c;标准库还定义了三个顺序容器适配器&#xff1a;stack、queue和priority_queue适配器(adaptor)是标准库中的一个通用概念。容器、迭代器和函数<369I都有适配器。本质上&#xff0c;一个适配器是一种机制&#xff0c;能使某种事物的…

SpringBoot Controller接收参数的常用方式

文章目录一、请求路径参数1、PathVariable二、Body参数1、RequestParam2、RequestBody三、请求头参数和Cookie参数1、RequestHeader2、CookieValue一、请求路径参数 1、PathVariable 注解为&#xff1a; org.springframework.web.bind.annotation.PathVariable获取路径参数&…

C++primer第十章 泛型算法 10.1 概述 10.2 初识泛型算法

大多数算法都定义在头文件algorithm中。标准库还在头文件numeric中定义了 一组数值泛型算法一般情况下&#xff0c;这些算法并不直接操作容器&#xff0c;而是遍历由两个迭代器指定的一个元素范围(参见9.2.1节&#xff0c;第296页)来进行操作。通常情况下&#xff0c;算法遍历范…

MySQL Mac安装教程

文章目录一、下载安装包二、安装三、启动MySQL四、环境变量设置一、下载安装包 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 二、安装 双击安装包&#xff0c;然后一直点继续即可。 三、启动MySQL 打开 系统偏好设置&#xff0c;会发现多了一个…

C++生成指定范围内的随机数

代码 rand&#xff08;&#xff09;% 3 &#xff1b; 3就是范围&#xff0c;代表生成[0,3)之间的随机数 int main(){for (int i 0; i < 20; i) {switch (rand() % 3) {case 0:std::cout << "00" << std::endl;case 1:std::cout << "11&q…

C++primer第十章 泛型算法 10.3 定制操作

10.3定制操作 很多算法都会比较输入序列中的元素。默认情况下&#xff0c;这类算法使用元素类型的&#xff1c;或运算符完成比较。标准库还为这些算法定义了额外的版本&#xff0c;允许我们提供自己定义的操作来代替默认运算符。例如&#xff0c;sort算法默认使用元素类型的&l…

C++primer第十章 泛型算法 10.4 再探迭代器 10.5 泛型算法结构

除了为每个容器定义的迭代器之外&#xff0c;标准库在头文件iterator中还定义了额外几种迭代器。这些迭代器包括以下几种。插入迭代器(insert iterator)&#xff1a;这些迭代器被绑定到一个容器上&#xff0c;可用来向容器插入元素。流迭代器(stream iterator)&#xff1a;这些…

C++primer第十一章 关联容器 11.1使用关联容器 11.2 关联容器概述

关联容器和顺序容器有着根本的不同&#xff1a;关联容器中的元素是按关键字来保存和访问的。与之相对&#xff0c;顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。虽然关联容器的很多行为与顺序容器相同&#xff0c;但其不同之处反映了关键字的作用关联容器支持高…

Redis Mac下安装与使用

目录一、下载安装包二、编译三、服务端与客户端命令1、服务端启动命令2、客户端连接命令3、服务端关闭命令一、下载安装包 官网地址&#xff1a;http://redis.io/download 下载后&#xff0c;解压放到任意目录下。 二、编译 打开终端&#xff0c;切换到 Redis 根目录&#x…

C++primer第十一章 关联容器 11.3关联容器操作 11.4 无序容器

11.3关联容器操作 除了表9.2(第295页)中列出的类型&#xff0c;关联容器还定义了表11.3中列出的类型。这些类型表示容器关键字和值的类型。对于set类型&#xff0c;key_type和value type是一样的&#xff1b;set中保存的值就是关键字。在一个map中&#xff0c;元素是关键字_值…

SpringBoot 整合Dubbo

文章目录一、工程目录结构二、创建工程项目1、创建接口工程&#xff08;cw-dubbo-api&#xff09;&#xff08;1&#xff09;pom.xml&#xff08;2&#xff09;创建接口类&#xff08;LoginService&#xff09;2、创建服务提供者工程&#xff08;cw-dubbo-provider&#xff09;…

C++primer第一章 开始

运算符打印endl,这是一个被称为操纵符(manipulator)的特殊值。写入endl 的效果是结束当前行&#xff0c;并将与设备关联的缓冲区(buffer)中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中&#xff0c;而不是仅停留在内存中等待写入流…

硬盘 相关知识

磁盘存储数据于轨道上&#xff0c;为了防止数据不被干扰&#xff0c;轨道之间是存在间隙的。如果间隙越小存储的数据越多&#xff0c;但是对数据的写入和读取所使用的磁头是不一样的&#xff0c;写入的磁头比较宽&#xff0c;读取的磁头比较窄。叠瓦式硬盘&#xff0c;将轨道和…

C++primer 第 2 章 变量和基本类型

2.1 基本内置类型 算术类型&#xff08;arithmetictype&#xff09;和空类型&#xff08;void&#xff09;在内的基本数据类型。其中算术类型包含了字符、整型数、布尔值和浮点数。空类型不对应具体的值&#xff0c;仅用于一些特殊的场合&#xff0c;例如最常见的是&#xff0…

SpringBoot 集成Mybatis

文章目录一、创建SpringBoot项目二、添加Mybatis相关依赖三、数据源配置四、创建事务的模型实体类五、创建和数据库交互联系的映射关系类六、创建业务接口和实现类七、创建控制器类八、请求验证一、创建SpringBoot项目 如何创建详见&#xff1a;IDEA 创建 SpringBoot 项目 二、…

C++primer 第 3 章 字符串、向量和数组 3.1 命名空间的using声明 3.2标准库类型string

引言 除了第2章介绍的内置类型之外,C语言还定义了 -个内容丰富的抽象数据类型库。其中,string和 vector是两种最重耍的标准库类型&#xff0c;前者支持可变长字符串&#xff0c;后者则 表示可变长的集合。还有…种标准库类型是迭代器&#xff0c;它是string和vector的配套类型…

C++primer 第 3 章 字符串、向量和数组 3 . 3 标准库类型vector

标准库类型vector表示对象的集合&#xff0c;其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引&#xff0c;索引用于访问对象。因为vector"容纳着”其他对象&#xff0c;所以它也常被称作容器(container).第 II部将对容器进行更为详细的介绍。 要想使用…

SpringBoot AOP切面实现

文章目录一、AOP简介二、AOP体系与概念三、AOP实例1、创建SpringBoot工程2、添加依赖3、AOP相关注解3.1、Aspect3.2、Pointcut3.2.1、execution()3.2.2、annotation()3.3、Around3.4、Before3.5、After3.6、AfterReturning3.7、AfterThrowing一、AOP简介 AOP&#xff08;Aspec…