[精進C++]C++處理字符串常用方法

2022-01-26 JTLinux
C++ find()函數用法
舉個例子:
#include <iostream>     // std::cout#include <algorithm>    // std::find#include <vector>       // std::vectorusing namespace std;int main() {    //find() 函數作用於普通數組    char stl[] ="http://c.biancheng.net/stl/";    //調用 find() 查找第一個字符 'c'    char * p = find(stl, stl + strlen(stl), 'c');    //判斷是否查找成功    if (p != stl + strlen(stl)) {        cout << p << endl;    }    //find() 函數作用於容器    std::vector<int> myvector{ 10,20,30,40,50 };    std::vector<int>::iterator it;
it = find(myvector.begin(), myvector.end(), 30); if (it != myvector.end()) cout << "查找成功:" << *it; else cout << "查找失敗"; return 0;}

對於 find() 函數的底層實現,C++ 標準庫中給出了參數代碼,感興趣的讀者可自行研究:

template<class InputIterator, class T>InputIterator find (InputIterator first, InputIterator last, const T& val){    while (first!=last) {        if (*first==val) return first;        ++first;    }    return last;}

查找第一次出現的目標字符串:

#include<iostream>#include<cstdio>using namespace std;
int main(){string s1 = "abcdef";string s2 = "de";int ans = s1.find(s2) ;   //在S1中查找子串S2cout<<ans<<endl;system("pause");}

說明:如果查找成功則輸出查找到的第一個位置,否則返回-1;

查找從指定位置開始的第一次出現的目標字符串:

#include<iostream>#include<csdtio>using namespace std;
int main(){string s1 = "abcdef";string s2 = "de";int ans = s1.find(s2, 2) ;   //從S1的第二個字符開始查找子串S2cout<<ans<<endl;system("pause");}

find_first_of()表示查找字符串的某個字符最先出現的位置,find_first_of()不是全匹配,即它不是必須要查找的字符串在被查找的字符串中全部出現,而是出現個別字符即可。(我覺得這是個神馬需求?沒用過!!!)

find_last_of()函數與find_first_of()功能差不多,只不過find_first_of()是從字符串的前面往後面搜索,而find_last_of()是從字符串的後面往前面搜索。

rfind()函數是反向查找字符串,即找到最後一個與子串匹配的位置。

find_first_not_of()函數是找到第一個不與子串匹配的位置。(這個也沒有用到過)

2、C++ substr()

substr()是C++語言函數,主要功能是複製子字符串,要求從指定位置開始,並具有指定的長度。如果沒有指定長度_Count或_Count+_Off超出了源字符串的長度,則子字符串將延續到源字符串的結尾。——摘自百科詞條

語法:

substr(size_type _Off = 0,size_type _Count = npos)一種構造string的方法

形式 :s.substr(pos, len)

返回值:string,包含s中從pos開始的len個字符的拷貝(pos的默認值是0,len的默認值是s.size() - pos,即不加參數會默認拷貝整個s)

異常 :若pos的值超過了string的大小,則substr函數會拋出一個out_of_range異常;若pos+n的值超過了string的大小,則substr會調整n的值,只拷貝到string的末尾

#include<iostream>#include<string>using namespace std;int main(){  string s="sfsa";  string a=s.substr(0,3);  string b=s.substr();  string c=s.substr(2,3);  cout<<a<<endl;  cout<<b<<endl;  cout<<c<<endl;  return 0;}

3、C++ replace() (這變態,重載了9個,給我挑的上氣不接下氣,不管他重載多少我們快速找出最適合自己那一款就好)

用法一:用str替換指定字符串從起始位置pos開始長度為len的字符

用法二: 用str替換 迭代器起始位置 和 結束位置 的字符

用法三: 用substr的指定子串(給定起始位置和長度)替換從指定位置上的字符串 

用法四:string轉char*時編譯器可能會報出警告,不建議這樣做

用法五:string轉char*時編譯器可能會報出警告,不建議這樣做

用法六:string轉char*時編譯器可能會報出警告,不建議這樣做

用法七:string轉char*時編譯器可能會報出警告,不建議這樣做

用法八: 用重複n次的c字符替換從指定位置pos長度為len的內容

用法九: 用重複n次的c字符替換從指定迭代器位置(從i1開始到結束)的內容 

這九個介紹往這裡一列給人看的腦瓜子嗡嗡的!

上例子!!!(這邊我寫3個,其他的都是大同小異的東西,一通百通;用的時候稍微Baidu一下瞬間會了,平時經常不用也記不住)

用法一:用str替換指定字符串從起始位置pos開始長度為len的字符

string& replace (size_t pos, size_t len, const string& str);

#include<iostream>#include<string>using namespace std;int main(){string str = "he is@ a@ good boy";str=str.replace(str.find("a"),2,"#");  //從第一個a位置開始的兩個字符替換成#cout<<str<<endl; return 0;}

用法二: 用str替換 迭代器起始位置 和 結束位置 的字符string& replace (const_iterator i1, const_iterator i2, const string& str);

#include<iostream>#include<string>using namespace std;int main(){string str = "he is@ a@ good boy"; str=str.replace(str.begin(),str.begin()+5,"#"); //用#替換從begin位置開始的5個字符 cout<<str<<endl; return 0; }

用法三: 用substr的指定子串(給定起始位置和長度)替換從指定位置上的字符串 

string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);

#include<iostream>#include<string>using namespace std;int main(){string str = "he is@ a@ good boy"; str=str.replace(str.begin(),str.begin()+5,"#"); //用#替換從begin位置開始的5個字符 cout<<str<<endl; return 0; }

4、C++中string::npos的一些用法總結

npos是一個常數,表示size_t的最大值(Maximum value for size_t)。許多容器都提供這個東西,用來表示不存在的位置,類型一般是std::container_type::size_type。

#include <iostream>  #include <limits>  #include <string>  using namespace std;  
int main() { size_t npos = -1; cout << "npos: " << npos << endl; cout << "size_t max: " << numeric_limits<size_t>::max() << endl;}

執行結果為:

                 npos:           4294967295

                 size_t max:  4294967295

可見他們是相等的,也就是說npos表示size_t的最大值

npos可以表示string的結束位置,是string::type_size 類型的,也就是find()返回的類型。find函數在找不到指定值的情況下會返回string::npos。舉例如下(計算字符串中含有的不同字符的個數):

#include <iostream>#include <string>using namespace std;int main(){    string b;    getline(cin,b);    int count=0;    for(int i=0;i<=127;i++)        if(b.find(i)!=string::npos)        count++;    cout<<count;}

string::npos作為string的成員函數的一個長度參數時,表示「直到字符串結束(until the end of the string)」。例如:

tmpname.replace(idx+1, string::npos, suffix);

這裡的string::npos就是一個長度參數,表示直到字符串的結束,配合idx+1表示,string的剩餘部分。

#include <iostream>  #include <limits>  #include <string>  using namespace std;  int main()  {      string filename = "test.cpp";      cout << "filename : " << filename << endl;  
size_t idx = filename.find('.'); //as a return value if(idx == string::npos) { cout << "filename does not contain any period!" << endl; } else { string tmpname = filename; tmpname.replace(idx + 1, string::npos, "xxx"); //string::npos作為長度參數,表示直到字符串結束 cout << "repalce: " << tmpname << endl; } } 

執行結果如下:

filename:test.cpp

replace: test.xxx

值得注意的地方:

int idx = str.find("abc");if (idx == string::npos)  ...

上述代碼中,idx的類型被定義為int,這是錯誤的,即使定義為 unsigned int 也是錯的,它必須定義為 string::size_type。因為 string::size_type (由字符串配置器 allocator 定義) 描述的是 size,故需為無符號整數型別。因為預設配置器以型別 size_t 作為 size_type,於是 -1 被轉換為無符號整數型別,npos 也就成了該型別的最大無符號值。不過實際數值還是取決於型別 size_type 的實際定義。不幸的是這些最大值都不相同。事實上,(unsigned long)-1 和 (unsigned short)-1 不同(前提是兩者型別大小不同)。因此,比較式 idx == string::npos 中,如果 idx 的值為-1,由於 idx 和字符串string::npos 型別不同,比較結果可能得到 false。

要想判斷 find() 的結果是否為npos,最好的辦法是直接比較:

if (str.find("abc") == string::npos) { ... }

寫在最後的一句話:

萬丈高樓平地起,再普通的改變也能改變普通。

相關焦點

  • 跟我學C++中級篇——STL中的字符串
    一、字符串在傳統的C/C++語言中,對字符串的處理比較麻煩,基本都是用char*來操作,而指針又往往是一個初學者的噩夢。STL為了解決這個問題,提供了std::string這個數據結構,其實它就是一個類,不過其提供了常見的對字符串的操作符的重載,實現在實際工程中經常遇到的字符串的長度計算,拼接和裁剪以及和C類型字符串的轉換。它不算是STL的容器,它只是一個類。
  • c++ fstream + string 處理大數據
    起因(1)之前處理文本數據時,各種清洗數據用的都是java的File,FileReader
  • c++的輸入與輸出
    c++輸入與輸出C++ 標準庫提供了一組豐富的輸入/輸出功能,本章將討論 C++ 編程中最基本和最常見的 I/O 操作。輸入輸出並不是c++語言的正式組成成分,c和c++沒有為輸入輸出提供專門的結構。在c語言中輸入輸出是通過調用scanf和printf 實現的,在c++中是通過調用流對象cin和cout實現的。
  • c++ fstream + string處理大數據
    一:起因(1)之前處理文本數據時
  • C++之字符串類學習總結
    ,所以更加無法獲得字符串類型為了解決這個問題,在c++中,引入了自定義類型,而且可以通過類來完成對字符串類型的定義。那麼C++中的原生類型系統是否包含字符串類型呢?答案是c++中並沒有提供原生的字符串類型。
  • C++、java 和 C 的區別
    一、基礎類型c++:** java:** C#:1.以java為準,c++裡面的int short long 像這樣的整型 一般都有unsigned 和signed的區分 ,這個跟java和c# 的區別比較大,但c#裡面有unit ulong ushort 這三種就相當於c++的修飾詞unsigned,當c++李明的變量類型定義unsigned,就默認是整數。
  • json for modern c++的使用
    json for modern c++是一款非常好用的json庫,具有語法直觀和使用簡單的特點,並且是用C++11標準編寫的,此外還支持STL和json容器之間的轉換,可謂集方便又強大。本文推薦給廣大C++程式設計師,相信學習完本文之後,在處理json時一定會得心應手。
  • 跟我學C++中級篇——STL的學習
    一、c++標準庫C++的標準庫主要包含兩大類,首先是包含C的標準庫的,當然,為了適應c++對一些C庫進行了少許的修改和增加。最重要的當然是面向對象的c++庫;而c++庫又可以分成兩大類,即面向對象的c++庫和標準模板庫,也就是題目中的STL。
  • C/C++中字符串與數字轉換
    作者:wxquare連結:https://www.cnblogs.com/wxquare/p/6529027.html本文總結了四種字符串和數字相互轉換的方法,方法一和方法二是c++中的方法,方法三和方法四是C語言庫函數的方法。
  • python+C、C++混合編程的應用
    我看到的一個很好的Python與c/c++混合編程的應用是NS3(Network Simulator3)一款網絡模擬軟體,它的內部計算引擎需要用高性能,但在用戶建模部分需要靈活易用。NS3的選擇是使用C/C++來模擬核心部件和協議,用python來建模和擴展。這篇文章介紹python和c/c++三種混合編程的方法,並對性能加以分析。
  • C++ 優先隊列priority_queue
    隊列排序一直在說優先隊列裡使用了排序,而常用的容器是 std::verctor,那麼究竟用的是什麼排序,又是在什麼時候進行的排序呢?+/datastruct$ g++ priorityqueue.cpp -o commonsort -std=c++11albert@home-pc:/mnt/c++/datastruct$ .
  • C++ 基礎概念總結第二篇:數據類型
    那這篇可太水了,不看了 可能你看見標題的時候又會覺得我在胡謅瞎侃,佔用大篇幅來寫這些有的沒的,但是你要是學過半小時c++編程的話你就應該知道,奧,這玩意可能不至於像聽起來那麼直白。  Int是中規中矩的那種數據,作為我們平時簡單編程最常用的整形它有四個字節(32bit),是short的兩倍;取值範圍是(-2^31——2^31-1)沒什麼特別的,老實,中庸,實用,就像身邊的很多人一樣
  • C++基礎總結(一):從「hello world」入門C++!
    面向對象程序設計c++最大的亮點就是面向對象程序設計理念的運用。包括面向對象開發的四大特性:封裝;抽象;繼承;多態C++的組成部分標準的 C++ 由三個重要部分組成:核心語言,提供了所有構件塊,包括變量、數據類型和常量,等等。
  • 那些容易犯錯的c++保留字
    本文首發 | 公眾號:lunvey目前正在學習vc++6.0開發,而這裡面使用的是c++98標準。
  • [C++]從Android10 編譯出現fallthrough錯誤,並介紹C++ attribute: fallthrough
    解決方式是加一行[[fallthrough]];即可。因為"[[fallthrough]];"是c++17的語法。為了更好兼容性。改為if的條件語句替換switch語句。當然換if條件語句代價就是代碼變得更難讀了。
  • c++11新特性,所有知識點都在這了!
    c++11新特性吧,你是怎麼回答的呢?,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內存管理還是c++語言的優勢,因為盡在掌握。+11中很常用,std::unique_ptr就是通過delete修飾來禁止對象的拷貝的。
  • 學習c++筆記——標準輸出流cout
    前和往常一樣,一邊喝早茶,一邊上網和女粉絲侃大山,在手機和平板電腦上整理修改《html5》、《javascript》、《css3》、《c語言》等多年前寫的教程(c++
  • 「最佳實踐」C++陷阱與套路
    ## 哈希減少字符串比較,構建hash,可能會多費一點存儲空間,但收益可觀,值得一試。## 常用數據結構**數組**:內存連續,隨機訪問,性能高,局部性好,不支持動態伸縮,最常用,通常也是最正確的選擇。
  • c++入門教程-1
    但是,C++的開發效率確實比C要高很多,所以我仍然採用斷章取義的方法來介紹C++的知識。不管是C還是C++,實用就好。一、C++程序的命名規則C++頭文件一般採用.h後綴,也用有.hpp的。1、安裝g++編譯器用root用戶登錄伺服器,執行以下命令安裝或升級gcc-c++編譯器。yum -y install gcc-c++如果您的CentOS系統沒有安裝gcc-c++,以上命令就會安裝最新版本的gcc-c++,如果已經安裝了gcc-c++,就會更新到最新版本的gcc-c++,所以,以上命令不管執行多少次都沒有問題。
  • C++ 的字符串是什麼樣子的?
    今天,我給大家帶來 C++ 中 string 類的介紹~Part2string 類的基本介紹string 類是 C++ 中常用的一個類,相比於 C 語言風格中的字符數組和字符串,string 類處理起來會方便很多。