C++中 string 中的方法的使用詳解(心得)

来源:https://www.cnblogs.com/maoqifansBlog/archive/2020/03/25/12571138.html
-Advertisement-
Play Games

string 字元串在所有的語言中都非常重要,c++也不例外,接下來我們將介紹string中的常用方法 1. size() 和 length() 函數 : 他們返回字元串的真實長度,且不會因為空格而截斷,這兩個方法完全等價,使用及輸出如下: #include<iostream> #include<s ...


string 字元串在所有的語言中都非常重要,c++也不例外,接下來我們將介紹string中的常用方法

1. size() 和 length() 函數 : 他們返回字元串的真實長度,且不會因為空格而截斷,這兩個方法完全等價,使用及輸出如下:

#include<iostream>
#include<string>
using namespace std;
 
int main(void)
{
    string s = "dasddasd";
    printf("size()返回的長度為:%lu\nlength()返回的長度為:%lu",s.size(),s.length());
    return 0;
}

 

2. find()函數和rfind()函數 : 這兩個函數用於查找字串在母串中的位置,並且返回該位置,當然如果找不到就會返回一個特別的標記string::nops,而find()函數是從字元串開始指針向後進行查找,rfind()函數是從字元串的結束指針開始向前查找,其使用及輸出如下:

 

#include<iostream>
#include<string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    int index = s.find("h");     // 從串首向後查找
    int index2 = s.find("h",2)   // 固定位置後子串在母串的位置
    int index1 = s.rfind("h");  // 從串尾向前查找
    printf("(find()):字母h在母串中的位置為:%d\n", index); 
    printf("(rfind()):字母h在母串中的位置為:%d", index1);
    return 0;
}

值得註意的是我們可以通過組合使用這兩個函數來實現判斷該子串是否唯一存在於母串中,其實現代碼如下:

#include<iostream>
#include<string>
using namespace std;

inline bool whetherOnly(string &str,string &base){
    return base.find(str) == base.rfind(str); 
}

 

3. find_last_of()函數和find_first_of()函數:從函數名我們也可以知道find_last_of()函數是找這個子串在母串中最後一次出現的位置並且將該位置返回;而find_first_of()函數是找這個子串在母串中最後一次出現的位置並將該位置返回,其使用及輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
  
    int index = s.find_first_of("h");
    int index1 = s.find_last_of("h");
    printf("(find_first_of()):字母h在母串中的位置為:%d\n", index);
    printf("(find_last_of()):字母h在母串中的位置為:%d", index1);
}

 

 

4.assign()函數:該函數用於將目標串的值複製到該串上,並且只複製值,其使用及輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    s.clear();
    s.assign("hello world");
    cout<<s<<endl;
    
}

 

5.clear()函數,把當前字元串清空,這時候如果調用string::size()函數或string::length()函數將返回0,其使用及輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    s.clear();
    cout<<"clear後的串的長度"<<s.size()<<endl;
}

 

6.resize()函數,該函數可以將字元串變長到指定長度,若小於原本字元串的長度,則會截斷原字元串;這個函數的一個重載形式是str.resize(length,'s') 可以用該輸入字元's'來對字元串進行擴充至length的長度,該函數的使用及輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    s.resize(5);       // s會變為 hello
    cout<<s<<endl;
    s.resize(10,'C'); // s 會變為 helloCCCCC
    cout<<s<<endl;
    
}

 

7. replace(pos,len,dist)函數: 該函數用於將該串從pos位置開始將長度為len的字串替換為dist串,值得註意的是該函數只替換一次,這與市面上的py和java等語言不一樣,需要留意,該函數的使用和輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    s.replace(s.find("h"),2,"#"); // 把從第一個h開始的兩個字元變為一個字元 #
    cout<<"替換後的字元串為: "<<s<<endl;
    
}

那麼既然C++本身不提供,替換所有子串的函數,我們就自己實現一個,其代碼如下:

// 替換字元串里的所有指定字元
string replace(string &base, string src, string dst) //base為原字元串,src為被替換的子串,dst為新的子串
{
    int pos = 0, srclen = src.size(), dstlen = dst.size();
    while ((pos = base.find(src, pos)) != string::npos)  
    {
        base.replace(pos, srclen, dst);
        pos += dstlen;
    }
    return base;
}

8. erase(index,length)函數:該函數刪除index位置後length長度的子串,其代碼及輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    s.erase(s.find("h"),3);
    cout<<"擦除過後的串"<<s<<endl; // 將會輸出lo worldh
}

 

9.substr(index,length)函數:該函數從index開始截斷到長度為length並返回截斷的子串;值得註意的是,該函數不改變母串的值,其使用及輸出如下:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    s = s.substr(0,5); 
    cout<<"截斷並賦值後的字元串為:"<<s<<endl; // 會輸出hello
}

 

10 . push_back(char c)函數,pop_back()函數,append(string s)函數:push_back(char c)函數往該字元串的尾端加入一個字元;pop_back()函數從該字元串的尾端彈出一個字元;而apend(string s)函數將會在該字元串的末尾添加一個字元串,並且返回添加後字元串的引用。他們的使用及輸出如下圖所示:

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
    string s = "hello worldh";
    // s.erase(s.find("h"),3);
    s.pop_back(); //彈出串的最後一個元素
    cout<<"彈出串尾元素後的字元串為: "<<s<<endl;
    s.push_back('s'); // 在串的最後添加一個字元
    cout<<"往串尾添加字元後的字元串為: "<<s<<endl;
    s.append("hhh"); // 在串的最後添加一個字元串
    cout<<"往串尾添加字元串後的字元串為: "<<s<<endl;
}

 

以上就是string中比較重要的函數的全部內容了,既然我們學完了該內容,那我們接下來做一條題來熟悉一下這些函數中的一些吧(題目與代碼如下代碼塊,題目出自leetcode):

 1 // 給你一份『辭彙表』(字元串數組) words 和一張『字母表』(字元串) chars。
 2 // 假如你可以用 chars 中的『字母』(字元)拼寫出 words 中的某個『單詞』(字元串),那麼我們就認為你掌握了這個單詞。
 3 
 4 // 註意:每次拼寫時,chars 中的每個字母都只能用一次。
 5 // 返回辭彙表 words 中你掌握的所有單詞的 長度之和。
 6 
 7 // 輸入:words = ["cat","bt","hat","tree"], chars = "atach"
 8 // 輸出:6
 9 // 解釋:
10 // 可以形成字元串 "cat" 和 "hat",所以答案是 3 + 3 = 6。
11 
12 // 輸入:words = ["hello","world","leetcode"], chars = "welldonehoneyr"
13 // 輸出:10
14 // 解釋:
15 // 可以形成字元串 "hello" 和 "world",所以答案是 5 + 5 = 10。
16 
17 #include <iostream>
18 #include <vector>
19 #include <string>
20 using namespace std;
21 class Solution
22 {
23 public:
24     int countCharacters(vector<string> &words, string chars)
25     {
26         int count = 0;
27         bool flag = false;                     // 標記
28         string c_chars(chars);                 // 構造c_chars保存chars
29         for (int i = 0; i < words.size(); i++) // 迭代單詞表
30         {
31             if (c_chars.size() < words[i].size()) //如果單詞的字母多於可選字母,則跳過這個單詞
32                 continue;
33             for (int j = 0; j < words[i].size(); j++) // 迭代可選擇的字母
34             {
35                 int index = c_chars.find(words[i][j]);
36                 if (index != c_chars.npos) // 能找到這個字母
37                 {
38                     flag = true;
39                     c_chars.erase(index, 1); // 從c_chars()刪除這個字母
40                 }
41                 else
42                 {
43                     flag = false; // 不能找到,意味著不能組成這個單詞
44                     break;        //跳出這次迴圈
45                 }
46             }
47             if (flag) // 如果符合則計數加1
48                 count += words[i].size();
49             c_chars.assign(chars); // 把chars的值在再次賦值給c_chars
50         }
51         return count;
52     }
53 };

 

最後感謝大家的閱讀,string中這些的函數組合起來可以說是威力無窮,所以還是要好好掌握的。

以上就是這次隨筆的全部內容了;其中有小部分內容參考了一些其他文章;好了,我們下次見,謝謝大家。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 框架:具有很強的通用性,且封裝了一些通用實現方法的項目模板 (非同步框架): 高性能的網路請求 高性能的數據解析 高性能的持久化存儲 高性能的全站數據爬取 高性能的深度爬取 高性能的分散式 Scrapy環境安裝 IOS和Linux windows 安裝完成後,輸入 測試一下,出現如下圖顯示,即安裝成功 ...
  • 一、ItemPipeLine 1.爬蟲提取出的數據存入item之後,item中保存的數據需要進一步處理,比如:清洗,去重,存儲等 2.pipeline需要process_item函數 (1)process_item​:spider提出來的item作為參數出入,同時傳入的還有spider;此方法是必須 ...
  • 目錄 1. "安裝VSCode應用程式" 2. "安裝相關插件" 1. "漢化插件" 2. "C++編輯器插件" 3. "編寫配置文件" 1. "tasks.json" 2. "launch.json" 3. "c_cpp_properties.json" 第一步、安裝VSCode應用程式 打開 " ...
  • 1. 在執行python程式時遇到 ‘ModuleNotFoundError: No module named 'xxxxx'’ : 例如: 圖片中以導入第三方的 'requests' 模塊為例,此報錯提示找不到requests模塊。在python中,有的 模塊是內置的(直接導入就能使用)有的模塊是 ...
  • 近期在開發過程中,因為項目開發環境連接的mysql資料庫是阿裡雲的資料庫,而阿裡雲的資料庫版本是5.6的。而測試環境的mysql是自己安裝的5.7。因此在開發過程中有小伙伴不註意寫了有關group by的sql語句。在開發環境中運行是正常的,而到了測試環境中就發現了異常。 原因分析:MySQL5.7 ...
  • 隨著分散式技術的普及和海量數據的增長,io的能力越來越重要,java提供的io模塊提供了足夠的擴展性來適應。 我是李福春,我在準備面試,今天的問題是: java中的io有哪幾種? java中的io分3類: 1,BIO ,即同步阻塞IO,對應java.io包提供的工具;基於流模型,雖然直觀,代碼實現也 ...
  • 1. 概念 Reactive 非常適合低延遲、高吞吐量的工作負載。 Reactive Processing 是一種範式(規範),它使開發人員能夠構建非阻塞的、非同步的應用程式,這些應用程式能夠處理背壓(流控制) Reactive Streams 為無阻塞背壓的非同步流處理提供標準。 Reactor 是基 ...
  • 多態(Polymorphism)按字面的意思就是“多種狀態”。在面向對象語言中,介面的多種不同的實現方式即為多態。引用Charlie Calverts對多態的描述——多態性是允許你將父對象設置成為和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...