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.pswp.cn/news/446714.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446714.shtml
英文地址,請注明出處:http://en.pswp.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…