C++中string類的使用

目錄

一.string類

1.1為什么學習string類?

1.2.標準庫中的string類

二.string對象的元素訪問

?2.1.1使用operator[]與at實現訪問

2.1.2正向迭代器訪問

2.1.3反向迭代器訪問

2.1.4const正向迭代器(不能修改)

2.1.5const反向迭代器(不能修改)

2.1.6范圍for

三.string類對象的常見構造

三.?string類對象的容量操作

四.?string類對象的修改操作

?find

五.string類非成員函數

六.將string對象int互相轉換

6.1stoi 將string里第一次遇到的數字字符轉換成int

6.2, to_string 將數字轉化成string對象

七.vs和g++下string結構的說明

7.1vs下string的結構

7.2g++下string的結構


一.string類

1.1為什么學習string類?

C 語言中,字符串是以 '\0' 結尾的一些字符的集合,為了操作方便, C 標準庫中提供了一些 str 系列的庫函數,但是這些庫函數與字符串是分離開的,不太符合OOP 的思想,而且底層空間需要用戶自己管理,稍不留神可能還會越界訪問。
OJ 中,有關字符串的題目基本以 string 類的形式出現,而且在常規工作中,為了簡單、方便、快捷,基本 都使用string 類,很少有人去使用 C 庫中的字符串操作函數。

1.2.標準庫中的string類

string類的文檔介紹

1. 字符串是表示字符序列的類
2. 標準的字符串類提供了對此類對象的支持,其接口類似于標準字符容器的接口,但添加了專門用于操作
單字節字符字符串的設計特性。
3. string 類是使用 char( 即作為它的字符類型,使用它的默認 char_traits 和分配器類型 ( 關于模板的更多信 息,請參閱basic_string)
4. string類是basic_string模板類的一個實例,它使用char來實例化basic_string模板類,并用char_traits 和allocator作為basic_string的默認參數(根于更多的模板信息請參考basic_string)。
5. 注意,這個類獨立于所使用的編碼來處理字節 : 如果用來處理多字節或變長字符 ( UTF-8) 的序列,這個 類的所有成員( 如長度或大小 ) 以及它的迭代器,將仍然按照字節 ( 而不是實際編碼的字符 ) 來操作。
總結:
1. string 是表示字符串的字符串類
2. 該類的接口與常規容器的接口基本相同,再添加了一些專門用來操作 string 的常規操作。

3. string 在底層實際是: basic_string 模板類的別名, typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字節或者變長字符的序列。 使用string類時,必須包含#include頭文件以及using namespace std;

二.string對象的元素訪問

?2.1.1使用operator[]與at實現訪問

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello");//構造for (size_t i = 0; i < s.size(); i++)//讀{cout << s[i] << "  ";}cout << endl;for (size_t i = 0; i < s.size(); i++){cout << s.at(i) << "  ";}cout << endl;for (size_t i = 0; i < s.size(); i++)//寫,at同理{cout << s[i]+=1 << "  ";}}

operator[]與at的區別:

operator[]在元素越界訪問時,采用斷言,at采用拋出異常

2.1.2正向迭代器訪問

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::iterator it = s.begin();while (it != s.end())//讀{cout << *it << "  ";it++;}cout << endl;it = s.begin();while (it != s.end())//寫{*it += 1;cout << *it << "  ";}cout << endl;return 0;
}

2.1.3反向迭代器訪問

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::reverse_iterator it = s.rbegin();while (it != s.rend())//讀{cout << *it << "  ";it++;}cout << endl;it = s.rbegin();while (it != s.rend())//寫{*it += 1;cout << *it << "  ";}cout << endl;return 0;
}

2.1.4const正向迭代器(不能修改)

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::const_iterator it = s.begin();while (it != s.end())//讀{cout << *it << "  ";it++;}cout << endl;return 0;
}

2.1.5const反向迭代器(不能修改)

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::const_reverse_iterator it = s.rbegin();while (it != s.rend())//讀{cout << *it << "  ";it++;}cout << endl;return 0;
}

2.1.6范圍for

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");for(auto ch:s)//無法修改{cout<<ch<<"  ";}for(auto& ch:s)//可以修改{ch+=1;cout<<ch<<"  ";}return 0;
}

三.string類對象的常見構造

string()? ?重點無參構造函數
string(const char* s)? 重點用字符串構造對象
string(size_t n,char c)? 重點用n個字符構造對象
string(const string& s) 重點拷貝構造
string(const string& str,size_t pos,size_t len=npos)用str從下標(包括)之后len長度的內容,構造對象
string(const char* s,size_t n)用字符串前n個構造對象

template <class InputIterator first,InputIterator last>

string(InputIterator first,InputIterator last)

迭代器區間構造對象

注:第四個構造方法,中的npos,是string類中的一個被static修是的,類型為size_t(無符號整形),值為-1

#include<iostream>
#include<string>
using namespace std;int main()
{string s1;//無參構造string s2("abcdefg");//用字符串構造對象string s3(5, 's');//string類對象中包含n個字符string s4(s2);//拷貝構造string s5(s2, 0, 3);//用str從下標(包括)之后len長度的內容,構造對象string s6("abcdefg", 3);//用字符串前n個構造對象string s7(s6.begin(), s6.end());//迭代器區間構造對象cout << "s1=" << s1 << endl;cout << "s2=" << s2 << endl;cout << "s3=" << s3 << endl;cout << "s4=" << s4 << endl;cout << "s5=" << s5 << endl;cout << "s6=" << s6 << endl;cout << "s7=" << s7 << endl;return 0;
}

三.?string類對象的容量操作

size (重點)返回字串有效字符長度
length返回字符串有效長度
capacity??返回空間總大小
empty (重點)檢測字符串是否為空串,是返回true,否則返回false
clear (重點)清空有效字符
reserve (重點)為字符串預留空間
resize (重點)將有效字符個數改成n個,多出的空間用字符c填充

1.reverse(修改總容量)

#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");cout << s.size() << "  " << s.capacity() << endl;s.reserve(100);cout << s.size() << "  " << s.capacity() << endl;s.reserve(10);cout << s.size() << "  " << s.capacity() << endl;return 0;
}

reserve用于預開空間,如果開辟的空間小于原空間,并不會改變容量

2.resize(調整size)
#include<iostream>
#include<string>
using namespace std;int main()
{//resize(n)// resize(size_t n,char x)//分三種情況//1.  n<size//2.  n>size && n<=capacity//3.  n>capacitystring s("hello world");s.resize(10);//cout << s.size() << "  " << s.capacity() << "  " << s<<endl;s.resize(17);//將size改為17,多出來的用'\0'填充cout << s.size() << "  " << s.capacity() << "  " << s<<endl;s.resize(40, 'x');//將size改為40,多出來的位置用'x'填充cout << s.size() << "  " << s.capacity() << "  " << s<<endl;return 0;
}

resize用于調整size,當n大于容量是,會擴容,并用對于的字符填充。

當n>size && n< 容量時,用對應的字符填充多出來的

當n<size 時,會縮容放棄超過的空間。

注意:
1. size() length() 方法底層實現原理完全相同,引入 size() 的原因是為了與其他容器的接口保持一
致,一般情況下基本都是用 size()
2. clear() 只是將 string 中有效字符清空,不改變底層空間大小。
3. resize(size_t n) resize(size_t n, char c) 都是將字符串中有效字符個數改變到 n 個,不同的是當字 符個數增多時:resize(n) 0 來填充多出的元素空間, resize(size_t n, char c) 用字符 c 來填充多出的 元素空間。注意:resize 在改變元素個數時,如果是將元素個數增多,可能會改變底層容量的大 小,如果是將元素個數減少,底層空間總大小不變。
4. reserve(size_t res_arg=0) :為 string 預留空間,不改變有效元素個數,當 reserve 的參數小于 string的底層空間總大小時, reserver 不會改變容量大小。

四.?string類對象的修改操作

push_back
在字符串后尾插字符c
append
在字符串后追加一個字符串
operator+= ( 重點)
在字符串后追加字符串 str
c_str ( 重點 )
返回 C 格式字符串
find + npos ( 重點 )
從字符串 pos 位置開始往后找字符 c ,返回該字符在字符串中的位置
rfind
從字符串 pos 位置開始往前找字符 c ,返回該字符在字符串中的位置
substr
str 中從 pos 位置開始,截取 n 個字符,然后將其返回

?find

//從pos位置開始找,str
size_t find (const string& str, size_t pos = 0) const noexcept;//從pos位置開始找字符串第一次出現的下標,若不存在返回npos	
size_t find (const char* s, size_t pos = 0) const;//從pos位置找字符串s的前n個第一次出現的下標,不存在返回npos
size_t find (const char* s, size_t pos, size_type n) const;size_t find (char c, size_t pos = 0) const noexcept;

通常finf與substr配合使用對找一個網址對應的協議,域名,地址

#include<iostream>
#include<string>
using namespace std;int main()
{
//string s3("https://legacy.cplusplus.com/reference/string/string/rfind/");string s3("ftp://www.baidu.com/?tn=65081411_1_oem_dg");// 協議// 域名// 資源名string sub1, sub2, sub3;size_t i1 = s3.find(':');if (i1 != string::npos)sub1 = s3.substr(0, i1);//查找協議elsecout << "沒有找到i1" << endl;size_t i2 = s3.find('/', i1+3);if (i2 != string::npos)sub2 = s3.substr(i1+3, i2-(i1+3));//查找域名elsecout << "沒有找到i2" << endl;sub3 = s3.substr(i2 + 1);//查找地址cout << sub1 << endl;cout << sub2 << endl;cout << sub3 << endl;
}

五.string類非成員函數

operator+ ?
盡量少用,因為傳值返回,導致深拷貝效率低
operator>> (重點)
輸入運算符重載
operator<< (重點)
輸出運算符重載
getline (重點)
獲取一行字符串
流提取不能接受空格和換行,需要用接受帶有空格的字符串時,可以用getline
getline
istream& getline(istream& in, string&str, char delim);//從流提取中提取字符串到str中,直到delim或'\n'istream& getline(istream& in,string& str, char);//從流提取中取字符串到str

六.將string對象int互相轉換

6.1stoi 將string里第一次遇到的數字字符轉換成int

將一個string對象轉化成int類型的數字
idx不傳參為nullptr,表示不使用這個參數,反之,&idx指向string對象數字字符的后一個位置

6.2, to_string 將數字轉化成string對象

七.vs和g++下string結構的說明

注意:下述結構是在 32 位平臺下進行驗證, 32 位平臺下指針占 4 個字節

7.1vs下string的結構

string 總共占 28 個字節 ,內部結構稍微復雜一點,先是 有一個聯合體,聯合體用來定義 string 中字
符串的存儲空間
當字符串長度小于 16 時,使用內部固定的字符數組來存放
當字符串長度大于等于 16 時,從堆上開辟空間
union _Bxty
{ // storage for small buffer or pointer to larger onevalue_type _Buf[_BUF_SIZE];pointer _Ptr;char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;
這種設計也是有一定道理的,大多數情況下字符串的長度都小于 16 ,那 string 對象創建好之后,內
部已經有了 16 個字符數組的固定空間,不需要通過堆創建,效率高。
其次:還有 一個 size_t 字段保存字符串長度,一個 size_t 字段保存從堆上開辟空間總的容量
最后:還 有一個指針 做一些其他事情。
故總共占 16+4+4+4=28 個字節。

7.2g++下string的結構 ???????

G++ 下, string 是通過寫時拷貝實現的, string 對象總共占 4 個字節,內部只包含了一個指針,該指
針將來指向一塊堆空間,內部包含了如下字段:
空間總大小
字符串有效長度
引用計數
struct _Rep_base
{size_type _M_length;size_type _M_capacity;_Atomic_word _M_refcount;
};
指向堆空間的指針,用來存儲字符串。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209690.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209690.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209690.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機網絡知識點合集【王道計算機考研】

學習的最大理由是想擺脫平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;遲一天就多一天平庸的困擾。各位小伙伴&#xff0c;如果您&#xff1a; 想系統/深入學習某技術知識點… 一個人摸索學習很難堅持&#xff0c;想組團高效學習… 想寫博客但無從下手&#xff0c;急需…

維護真實時間:應對系統時間篡改的技巧

引言 在App使用中&#xff0c;由于系統時間用戶可以隨意更改&#xff0c;在某些特殊情況下會導致獲取到的系統時間不正確問題。本篇代碼使用dart語言進行相關描述。 1.問題分析&#xff1a; 手機系統時間 ≠ 真實時間&#xff0c;當我們做一些需要對時間精度和準確性要求較高的…

SQL命令---修改數據庫的編碼

介紹 使用sql命令修改數據庫的編碼&#xff0c;修改為utf8mb4編碼。 命令 alter database 數據庫名稱 default character set utf8mb4;

垃圾收集算法和各種垃圾收集器的實現

深入理解Jvm虛擬機第三章 二、對象已死&#xff1f;3.2.1 引用計數算法3.2.2 可達性分析算法3.2.3 再談引用3.2.4 生存還是死亡3.2.5 回收方法區 三、垃圾收集算法3.3.1 分代收集理論3.3.2 標記-清除算法3.3.3 標記-復制算法3.3.4 標記-整理算法 四、HotSpot的算法細節實現3.4.…

單片機中的printf思考

問題: 1. printf自帶的庫編譯出來的大小比較大(flash吃緊) 2. printf是一個不定長參數, 意味著函數無法知道傳入的長度. 解決這個問題有2中方法:1.設置足夠大小的數組作為參數存儲; 2. 使用動態內存分配的方式來做(應該使用的是這個方式).(內存吃緊) 問題解釋: 1. 之前寫裸…

C# WPF上位機開發(串口界面設計)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 如果只是把上位機看成是純軟件開發&#xff0c;本身不和硬件打交道的話&#xff0c;那么這就把上位機的操作范圍給限定死了。事實上&#xff0c;上…

多線程的使用

進程與線程 進程&#xff1a; 1、進程是指運行中的程序&#xff0c;比如我們使用QQ&#xff0c;就啟動了一個進程&#xff0c;操作系統就會為該進程分配內存空間。當我們使用微信&#xff0c;又啟動了一個進程,操作系統將為其分配新的內存空間。 2、進程是程序的一次執行過程…

數據庫系統概論期末經典大題講解(范式提升、求閉包、求主碼)

上一次我們介紹了數據庫中關系代數查詢&#xff0c;從選擇、投影到連接等操作符&#xff0c;探索了數據庫查詢 大家可以移步我的文章&#xff1a;數據庫系統概論期末經典大題講解&#xff08;用關系代數進行查詢&#xff09;-CSDN博客 今天&#xff0c;我們將繼續沿著數據庫系統…

《python每天一小段》--12 數據可視化《1》

歡迎閱讀《Python每天一小段》系列&#xff01;在本篇中&#xff0c;將使用Python Matplotlib實現數據可視化的簡單圖形。 一、概念 Matplotlib是一個流行的Python數據可視化庫&#xff0c;它提供了豐富的繪圖功能&#xff0c;可以創建各種類型的圖表&#xff0c;包括折線圖、…

Spring框架學習:Bean生命周期

目錄 SpringBean的生命周期 Bean實例屬性填充 三級緩存 常用的Aware接口 Spring IoC容器實例化Bean總結 SpringBean的生命周期 Spring Bean的生命周期是從 Bean 實例化之后&#xff0c;即通過反射創建出對象之后&#xff0c;到Bean成為一個完整對象&#xff0c;最終存儲到…

【MyBatis系列】MyBatis字符串問題

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

SpringBoot + Spring Cloud Alibaba + Nacos實現服務管理

1、參考文檔 Spring Cloud Alibaba參考文檔 https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html Spring Cloud Alibaba官方文檔 https://github.com/alibaba/spring-cloud-alibaba/wiki/ 2、引入 Alibaba 依賴 每個 SpringBoot 都有對應的…

css中2D和3D的區別

CSS中2D和3D的主要區別在于&#xff1a; 維度不同&#xff1a;2D是二維平面&#xff0c;3D是三維空間。可視角度不同&#xff1a;2D只能從一個平面角度看&#xff0c;而3D可以在多個角度上觀察。技術難度不同&#xff1a;3D效果需要更復雜的技術支持&#xff0c;如矩陣變換&am…

javascript實現Stack(棧)數據結構

上一篇文章我們理解了List這種數據結構&#xff0c;知道了它的特點和一些使用場景&#xff0c;這篇文章我們就來看一下棧這種數據結構&#xff0c;這里的棧可不是客棧哦&#xff0c;哈哈 棧其實和List非常像&#xff0c;使用javascript實現都是基于數組來實現 嘗試理解Stack …

6種常見的JS模塊打包器

前言 JS模塊打包器是一種工具&#xff0c;它可以將多個JS文件或模塊合并成一個或多個輸出文件&#xff0c;以便在瀏覽器或其他環境中使用。 JS模塊打包器的作用有&#xff1a; 優化代碼&#xff1a;通過壓縮、混淆、刪除無用代碼等方式&#xff0c;減少代碼的體積和復雜度&…

windows系統和虛擬機上ubuntu系統通過虛擬串口進行通信

本文的目的是實現windows系統和虛擬機上安裝的ubuntu通過串口進行通信。為了直觀觀測串口收發數據的內容&#xff0c;需要在windows系統和ubuntu系統使用串口助手來進行監聽。windows系統端用的監聽工具是串口助手SSCOM&#xff0c;ubuntu系統端使用的串口助手是CuteCom。 ubu…

OpenCL學習筆記(一)開發環境搭建(win10+vs2019)

前言 異構編程開發&#xff0c;在高性能編程中有重要的&#xff0c;筆者本次只簡單介紹下&#xff0c;如何搭建簡單的開發環境&#xff0c;可以供有需要的小伙伴們開發測試使用 一、獲取opencl的sdk庫 1.使用cuda庫 若本機有Nvidia的顯卡&#xff0c;在安裝cuda庫后&#x…

如何提高大模型在超長上下文的表現?Claude實驗表明加一句prompt立即提升效果~

本文來自DataLearnerAI官方網站&#xff1a;如何提高大模型在超長上下文的表現&#xff1f;Claude實驗表明加一句prompt立即提升效果~ | 數據學習者官方網站(Datalearner)https://www.datalearner.com/blog/1051701947131881 Claude 2.1版本的模型上下文長度最高拓展到200K&am…

【Flink系列四】Window及Watermark

3.1、window 在 Flink 中 Window 可以將無限流切分成有限流&#xff0c;是處理有限流的核心組件&#xff0c;現在 Flink 中 Window 可以是時間驅動的&#xff08;Time Window&#xff09;&#xff0c;也可以是數據驅動的&#xff08;Count Window&#xff09;。 Flink中的窗口…

c jpeg YUV圖片幀分割成 8*8 塊 ,與逆向把8*8還原為幀

1. 正向分割為若干8*8 塊 下面的程序為通用程序&#xff0c;可以分割任意塊 #include <stdlib.h> #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h>…