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…

codeforces 266A-C语言解题报告

266A题目网址 题目解析 1.输入n(1–50)个石头个数,输入RGB的石头颜色,求问拿走最小的石头个数,让它们相邻的石头颜色不同 代码 #include<stdio.h> #include<stdlib.h> #include<string.h> int main() {int n,i,count0;char s[50]{\0};scanf("%d&quo…

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轴变化…

Zookeeper 终端命令

目录一、服务端命令1、启动Zookeeper服务命令2、查看Zookeeper状态命令3、停止Zookeeper服务命令4、启动Zookeeper客户端命令二、客户端命令1、查看帮助2、查看当前znode所包含的内容3、创建znode4、创建短暂znode5、创建带序号znode6、创建短暂带序号znode7、获取znode数据8、…

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

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

codeforces 236A-C语言解题报告

236题目网址 题目解析 1.输入字符串,判断其中不同的字符个数,奇偶输出不同的语句 2.使用冒泡排序去排序,当遇到s[k]!s[k1]时进行计数 代码 #include<stdio.h> #include<stdlib.h> #include<string.h> int main() {char s [100]{\0};int i,j,k,count0;cha…

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;会发现多了一个…

codeforces 96A-C语言解题报告

96A题目网址 题目解析 1.输入0和1表示不同队的队员字符串,如果7个及以上的一个0或1在一起,则输出YES否则输出NO 举例: 输入: 1000000001 输出: YES 2.循环时,当遇到count7时输出YES并跳出循环,遇到s[i]!s[i1]时,将count重置为1,最后count<7再输出NO 代码 #include<s…

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…

MySQL 客户端命令

文章目录1、连接命令2、断开连接3、命令结束符4、查看所有数据库5、切换到指定数据库6、查看当前使用的数据库7、查看库中所有表8、查看所有用户9、执行SQL脚本10、查询当前时间1、连接命令 首先定位到MySQL安装根目录/bin目录下&#xff0c;然后执行如下命令&#xff1a; my…

SQL 库、表语句

文章目录一、数据库操作1、创建数据库2、删除数据库二、表操作1、创建表&#xff08;1&#xff09;主键&#xff08;primary key&#xff09;属性&#xff08;2&#xff09;unique属性&#xff08;3&#xff09;主键和unique约束的区别&#xff08;4&#xff09;外键&#xff0…

codeforces 69A-C语言解题报告

69A题目网址 题目解析 1.输入n个(x,y,z),当xi相加0;yi相加0;zi相加0同时时输出YES,否则输出NO 举例: 输入: 3 3 -1 7 -5 2 -4 2 -1 -3 输出: YES 2.注意点:使用二维数组去存放时,使用遍历行并对每一列分别相加 for(b0;b<n;b){count_xdir[b][0];count_ydir[b][1];count_z…

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

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

SQL 查询语句

文章目录1、简单查询2、去除单列的重复结果查询3、去除多列的重复结果查询4、限制查询结果条数5、对查询结果排序&#xff08;1&#xff09;按照单个列的值进行排序&#xff08;2&#xff09;按照多个列的值进行排序6、带搜索条件查询&#xff08;1&#xff09;简单搜索条件查询…

2000年考研英语阅读理解文章一

文章详细讲解网址 注意点 1.文章开篇第一句话往往是文章所想要通过后面讲解的事情表达出来的最终观点 2.当询问到作者观点时,往往在最后一段,一般以下形式呈现: 1)few people …(这就是作者的观点) 2)I think 后面举什么别人所说的话,如果不是表达了赞同,则都是别人的观点,而…

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

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

codeforces 546A-C语言解题报告

546A题目网址 题目解析 1.输入 k(成本),n(拥有的钱),w(要买的个数),输出还需要向朋友借多少钱? 举例: 输入: 3 17 4 输出: 13 2.注意: 1)第i个,需要i*k个价钱,所以需要使用for循环运算花费 2)当拥有的钱足够买时,不需要借钱,输出为0 代码 #include<stdio.h> #inclu…

java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误

文章目录1、报错信息2、原因分析3、解决方案1、报错信息 java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数 ORA-01000: 超出打开游标的最大数at oracle.jd…