目錄
一.為什么學習string類
(1) C語言中的字符串
(2)標準庫里面的string類
二. string類的常用接口說明
(1)string類對象的常見構(gòu)造
(2)string類對象的容量操作
1.size(),length().
2. capacity()
3.empty()
?4.clear()
?5.reserve()
?6.resize()
(3)string類對象的訪問及遍歷操作
?1.operator[ pos ] ,at(size_t pos)
?2.back(),front()
(4)string類的迭代器
1.begin(),end()
2.rbegin() ,rend()
3.范圍for
(5) string類對象的修改操作
1.push_bank( )
?2.append()
3.operator +=
?4.insert ()
?5.erase()
6.swap()
(6)字符串相關算法
1.c_str()
?2.find()
3.substr()
(7) 非成員函數(shù)重載
1.getline()
一.為什么學習string類
(1) C語言中的字符串
C語言中,字符串是以'\0'結(jié)尾的一些字符的集合,為了操作方便,C標準庫中提供了一些str系列的庫函數(shù),但是這些庫函數(shù)與字符串是分離開的,不太符合OOP的思想,而且底層空間需要用戶自己管理,稍不留神可能還會越界訪問。
在OJ中,有關字符串的題目基本以string類的形式出現(xiàn),而且在常規(guī)工作中,為了簡單、方便、快捷,基本都使用string類,很少有人去使用C庫中的字符串操作函數(shù)。
(2)標準庫里面的string類
string類文檔
- 字符串是表示字符序列的類
- 標準的字符串類提供了對此類對象的支持,其接口類似于標準字符容器的接口,但添加了專門用于操作單字節(jié)字符字符串的設計特性。
- string類是使用char(即作為它的字符類型,使用它的默認char_traits和分配器類型(關于模板的更多信息,請參閱basic_string)。
- string類是basic_string模板類的一個實例,它使用char來實例化basic_string模板類,并用char_traits和allocator作為basic_string的默認參數(shù)(根于更多的模板信息請參考basic_string)。
- 注意,這個類獨立于所使用的編碼來處理字節(jié):如果用來處理多字節(jié)或變長字符(如UTF-8)的序列,這個類的所有成員(如長度或大小)以及它的迭代器,將仍然按照字節(jié)(而不是實際編碼的字符)來操作。
總結(jié):
1. string是表示字符串的字符串類
2. 該類的接口與常規(guī)容器的接口基本相同,再添加了一些專門用來操作string的常規(guī)操作。
3. string在底層實際是:basic_string模板類的別名,typedef basic_string<char, char_traits, allocator>string;
4. 不能操作多字節(jié)或者變長字符的序列在使用string類時,必須包含#include頭文件以及using namespace std;
二. string類的常用接口說明
(1)string類對象的常見構(gòu)造
string() (重點) | 創(chuàng)建空的string類型對象,即空字符串 |
string(const char* s) (重點) | 用C-string來構(gòu)造string類對象 |
string(size_t n, char c) | string類對象中包含n個字符c |
string(const string&s) (重點) | 拷貝構(gòu)造函數(shù) |
#include<iostream>
#include<string>
using namespace std;
int main()
{
//創(chuàng)建空字符串
string str1;
cout << str1 << endl;
//使用字符串構(gòu)造對象
string str2("hello world");
cout << str2 << endl;
//使用n個字符構(gòu)造對象
string str3(15, '*');
cout << str3 << endl;
//拷貝構(gòu)造函數(shù)
string str4(str2);
cout << str4 << endl;
return 0;
}
(2)string類對象的容量操作
課件代碼/C++課件V6/string的接口測試及使用/TestString.cpp · will/C++上課 - Gitee.com
1.size(),length().
size()和lenth都是返回字符串有效長度的。
注意:我們一般表示字符串的長度時使用length,引入size()的原因是為了與其他容器的接口保持一致,一般情況下基本都是用size()。
int main()
{
string str("hello world");
cout << str.size() << endl;
cout << str.length() << endl;
return 0;
}
2. capacity()
capacity()是返回字符串對象的總空間大小的,因為string自己本身是可以擴容的。
int main()
{
string str("hello world");
cout << str.size() << endl;
cout << str.length() << endl;
cout << str.capacity() << endl;
return 0;
}
3.empty()
檢測字符串釋放為空串,是返回true,否則返回false。
int main()
{
string str("hello world");
string str1;
cout << str.empty() << endl;
cout << str1.empty() << endl;
return 0;
}
?4.clear()
清楚有效字符。
注意:clear()只是將string中有效字符清空,不改變底層空間大小。
int main()
{
string str("hello world hello world hello ");
cout << "clear前:" << str <<" 容量:" << str.capacity() << endl;
str.clear();
cout << "clear前:" << str << "容量:" << str.capacity() << endl;
return 0;
}
?5.reserve()
為字符串預留空間,我們直到在一些情況下如果我們提前知道了字符串的大小,就可以提前為字符串開好空間,避免后面的擴容帶來的效率上的消耗。
注意:實際上的申請后的空間會比我們申請的空間大一些,這也是一種保護機制。但是我們?nèi)绻覀冾A留的空間比原本的空間還要小時,此時函數(shù)會進行優(yōu)化,個根據(jù)我們存儲的串的長度經(jīng)行合適的改表。
?6.resize()
resize(size_t n) 與 resize(size_t n, char c)都是將字符串中有效字符個數(shù)改變到n個,不同的是當字符個數(shù)增多時:resize(n)用0來填充多出的元素空間,resize(size_t n, char c)用字符c來填充多出的元素空間。注意:resize在改變元素個數(shù)時,如果是將元素個數(shù)增多,可能會改變底層容量的大小,如果是將元素個數(shù)減少,底層空間總大小不變。如果 n 小于字符串長度,就刪去字符串保留前 n 個。
int main()
{
string str("abcde");
cout << str << endl;
//擴容+初始化
str.resize(str.size() + 5, '#');
cout << str << endl;
//減小長度
str.resize(4);
cout << str << endl;
return 0;
}
(3)string類對象的訪問及遍歷操作
?1.operator[ pos ] ,at(size_t pos)
operator [ ] 都是返回pos位置的字符,const string類對象調(diào)用。operater[ ]是對[ ]的運算符重載,就像數(shù)組一樣的訪問。
注意:兩者的區(qū)別在,處理越界方面,operator[ ]使用斷言處理,而 at(pos) 是拋出一個異常。
int main()
{
string str("hello");
for (int i = 0; i < str.size(); i++)
{
cout << str[i] << " ";
}
cout << endl;
for (int i = 0; i < str.size(); i++)
{
cout << str.at(i) << " ";
}
return 0;
}
?2.back(),front()
back():返回最后一字符,front():返回第一個字符。
(4)string類的迭代器
1.begin(),end()
begin():返回一個迭代器,該迭代器指向字符串的開始字符。
end():返回一個迭代器,該迭代器指向字符串的結(jié)束字符。
迭代器,也是一個用來遍歷對象的一個東西,它有自己的類型 iterator ,針對begin(),和end(),也都有自己的const版本,也就是僅可讀迭代器。string的迭代器的使用和指針差不多。
當前可以這么理解,隨著我們STL的不斷學習,會對迭代器有更加深刻的理解。
int main()
{
string str("helloworld");
//非const迭代器,可讀,可寫
for (string::iterator it = str.begin();it!=str.end();it++)
{
*it = '*';
}
for (string::iterator it = str.begin(); it != str.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//const 迭代器 僅可讀
const string str1("helloworld");
for (string::const_iterator it = str1.begin(); it != str1.end(); it++)
{
cout << *it << " ";
}
return 0;
}
2.rbegin() ,rend()
rbegin():返回反向迭代器以反向開始,返回一個反向迭代器,指向字符串的最后一個字符(即其反向開頭),反向迭代器向后迭代:增加迭代器會將它們移向字符串的開頭。
rend():返回一個反向迭代器,該迭代器指向字符串的第一個字符之前的理論元素(被視為其反向結(jié)尾)。
反向迭代器的類型是,reverse_iterator,同時都提供了,const版本。
int main()
{
string str("helloworld");
for (string::reverse_iterator it = str.rbegin(); it != str.rend(); it++)
{
cout << *it << " ";
}
return 0;
}
?
對于迭代器的類型寫起來非常的不方便,我們可以使用auto來自動識別。
3.范圍for
范圍for是將str對象的字符一個一個取出來,放到 c 中。其底層還是使用的迭代器。
int main()
{
string str("helloworld");
for (auto c : str)
{
cout << c << " ";
}
return 0;
}
(5) string類對象的修改操作
1.push_bank( )
在字符串后尾插字符c。
int main()
{
string str("hello");
cout << str << endl;
str.push_back('w');
str.push_back('o');
str.push_back('r');
str.push_back('l');
str.push_back('d');
cout << str<<endl;
return 0;
}
?2.append()
在字符串后追加一個字符串,同時也提供了多個版本:
string& append (const string& str):追加一個字符串 str 。 string& append (const string& str, size_t subpos, size_t sublen):追加字符串str的pos位置后的sublen個字符。 string& append (const char* s):追加一個C字符串,(即以‘/0’結(jié)束的字符串)。 string& append (const char* s, size_t n):追加C字符串s的后n個字符。 string& append (size_t n, char c):追加 n 個字符 c
int main()
{
string str;
string str1;
cout << str << endl;
string str2 = "Writing ";
//str1追加str2的第四個位置的后三個字符
str1.append(str2, 4,3);
//str追加str2
str.append(str2);
cout << str << endl;
cout << str1 << endl;
//str2z追加一個C字符串
str2.append("work");
cout << str2 << endl;
//str2追加一個c字符串的前兩個字符
str2.append("hello", 2);
cout << str2 << endl;
//str2追加10個‘#’
str2.append(10, '#');
cout << str2 << endl;
return 0;
}
3.operator +=
?對于上述的push_bank和append其實在string類中使用并不多,我們一般常用operator+=來追加字符串或者追加字符。
例:
int main()
{
string str1("hello");
string str2("world");
str1 += str2;
cout << str1 << endl;
return 0;
}
?4.insert ()
字符串插入函數(shù),可以支持在某一位,或者迭代器位置插入固定個數(shù)的字符,和字符串。
?例:文章來源:http://www.zghlxwxcb.cn/news/detail-641975.html
int main()
{
string str1("hello");
string str2("world");
int pos = 0;
//1.在pos位置插入一個 string
str2.insert(pos, str1);
cout << str2 << endl;
string str3("bcde");
int size = 5;
//2.在pos位置插入size個字符a
str3.insert(pos, size, 'a');
cout << str3 << endl;
string str4("bcde");
//3.插入位置還可以是迭代器
str4.insert(str4.begin(), 10, 'A');
cout << str4 << endl;
string str5("world");
const char* cstr = "hello ";
//3.在pos位置插入一個 C風格字符串。
str4.insert(pos,cstr);
cout << str5 << endl;
return 0;
}
?注意:insert,在插入時,特別是在字符串的前部插入是,會有字符的移動消耗。相當于順序表的頭插。
?5.erase()
rases字符串的一部分,縮短其長度。
例:
int main()
{
int pos = 5;
int size = 3;
string str1("hello C++");
string str2 = str1;
cout << "erase前str1:" << str1 << endl;
cout << "erase前str2:" << str2 << endl;
//刪除pos位置包括pos位置的后size個字符,刪除位置也可以是一段迭代器區(qū)間
str1.erase(pos, size);
str2.erase(str2.begin()+5,str2.begin()+5+3);
cout << "erase后str1:" << str1 << endl;
cout << "erase后str2:" << str2 << endl;
return 0;
}
注意:
- 如果給出的刪除個數(shù)大于字符串后面的字符數(shù),就會將后面字符全部刪除。
- 如果不給出刪除位置設定的缺省參數(shù)從0開始刪除。
- 如果不給出刪除個數(shù),缺省參數(shù)設定的刪除個數(shù)是 size_t npos = -1,約42億。
- 刪除以后字符串的長度(length)會變,但是容量(capacity)不會變。
6.swap()
swap交換函數(shù),非功能上非常簡單,就不多介紹了。但是在 std 里面也有一個swap,我們兩個swap來對比一下。
std::swap()底層是一個由借助函數(shù)模板實現(xiàn)。不僅僅可以對string類型,對任何可以修改的類型都可以實現(xiàn)交換。
原理類似:
template<class T>
void Swap(T& e1,T& e2)
{
T tmp = e1;
e1 = e2;
e2 = tmp;
}
string::swap()底層是交換string里面的字符串指針來實現(xiàn)的,總體效率要比std::swap()高得多。
(6)字符串相關算法
1.c_str()
返回一個C風格字符串。
?2.find()
在字符串中搜索由其參數(shù)指定的序列的第一個匹配項。
指定pos時,搜索僅包括位置pos處或之后的字符,忽略任何可能出現(xiàn)的位置pos之前的字符。
?例如:
int main()
{
string str = "this is a string";
//從1位置開始查找字符a,并返回位置。
size_t pos = str.find('a', 1);
cout << "a 在" << pos << "位置" << endl;
return 0;
}
?注意:
- 如果未給出查找位置,就從缺省位置0開始查找。
- 如果沒有找到會返回size_t npos = -1。
3.substr()
返回一個新構(gòu)造的字符串對象,該對象的值初始化為此對象的子字符串的副本。
子字符串是對象的一部分,從字符位置pos開始,跨越len個字符(或直到字符串結(jié)束,以先到者為準)。
例:
int main()
{
int pos = 0;
int length = 4;
string str = "this is a string";
//返回一個從pos位置開始,跨越長度為4的子串。
string Substr = str.substr(0, 4);
cout << "Substr:" << Substr << endl;
return 0;
}
?注意:
如果沒給出起始位置,缺省參數(shù)設置為0。
如果沒給出跨越長度,缺省參數(shù)設置為size_t npos = -1。
(7) 非成員函數(shù)重載
1.getline()
?從is中提取字符并將其存儲到str中,直到找到定界字符delim。沒有delim時默認是 ' \n '為定界符 。
?例:
int main()
{
string str;
cout << "輸入:";
std::getline(cin, str,'a');
cout << "str:" << str << endl;
return 0;
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-641975.html
到了這里,關于C++ STL string類的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!