真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++string類-創(chuàng)新互聯(lián)

在c語言中,我們想要記錄字符串需要創(chuàng)建一個字符串的數(shù)組,而c++則提供了另一種方式;

成都創(chuàng)新互聯(lián)是一家專業(yè)從事做網(wǎng)站、網(wǎng)站設(shè)計的網(wǎng)絡(luò)公司。作為專業(yè)的建站公司,成都創(chuàng)新互聯(lián)依托的技術(shù)實力、以及多年的網(wǎng)站運營經(jīng)驗,為您提供專業(yè)的成都網(wǎng)站建設(shè)、全網(wǎng)整合營銷推廣及網(wǎng)站設(shè)計開發(fā)服務(wù)!

也就是這篇博客所說的string類;

目錄

string類

string類的成員函數(shù)

string的構(gòu)造函數(shù)

string的容量操作函數(shù)

size() / length() / capacity() 函數(shù)

reserve(size_t n) / resize(size_t n, char c) 函數(shù)

string類對象的訪問及遍歷操作

operator[] (size_t pos)

begin()/end()/rbegin()/rend()

迭代器——iterator

string類對象修改操作

string的其他函數(shù)


string類

#include

作為字符串數(shù)組的升級版,string類自然也有它的獨特之處——可變長數(shù)組;

c語言中的字符串數(shù)組只能在創(chuàng)建的時候定好初始的長度,數(shù)據(jù)長度不能超過數(shù)組長度;

而string類則沒有這樣的顧慮,雖然string變量都有自己的初始長度,但是它內(nèi)部的成員函數(shù)會在輸入數(shù)據(jù)超過初始長度的時候,會自動開辟空間,因此可以不用考慮數(shù)組長度;

此外,c++考慮到需要兼容c語言,也給string類重載了一個類似于c語言創(chuàng)建字符串數(shù)組的構(gòu)造方式

但是這里有一點需要注意的是,雖然string類這里的創(chuàng)建方式和c語言的字符串數(shù)組一樣;

但是它還是有很多不同的;

首先就是它并不是以 ‘\0’ 作為結(jié)束的標志;

我們可以看下它內(nèi)部:

可以看到 s1 并不是以 '\0’ 作為結(jié)束標志的;

好,說了那么多 string類和 c語言數(shù)組的不同,那么來講講string類特有的功能吧;

string類的成員函數(shù)

string類中實現(xiàn)了許多成員函數(shù),并且每種函數(shù)根據(jù)不同的情況有不同的重載;

這里我們就認識一下用的比較多的函數(shù)吧;

string的構(gòu)造函數(shù)
?函數(shù)名稱功能? ? ??
string()創(chuàng)造一個空的string對象
string(const char* s)用一個字符串創(chuàng)建string對象
string(size_t n,char c)用 n 個 c 字符創(chuàng)建string對象
string(const string& s)用string對象拷貝構(gòu)造一個string對象

void test3()
{
	string s1;
	string s2("abcd");
	string s3(5, 'c');
	string s4(s3);

	cout<< "s1 = "<< s1<< endl;
	cout<< "s2 = "<< s2<< endl;
	cout<< "s3 = "<< s3<< endl;
	cout<< "s4 = "<< s4<< endl;


}

我們能夠看到,使用不同方式都成功創(chuàng)建了對應(yīng)的字符串;

string的容量操作函數(shù)
?函數(shù)名 功能
size()返回字符串有效字符長度
length()返回字符串有效字符長度
capacity()返回空間總大小
empty()檢測是否為空
clear()清空有效字符
reserve(size_t n = 0)為字符串開辟空間
resize(size_t n)/(size_t n ,char c)更改有效字符為n,多出的用字符c填充

c++中對于string的容量操作的函數(shù)可不少,我們先來一個一個學(xué)習(xí)吧;

size() / length() / capacity() 函數(shù)
void test4()
{
	string s1 = "hello world!";
	cout<< s1.size()<< endl;
	cout<< s1.length()<< endl;
	cout<< s1.capacity()<< endl;
}

首先是string的檢查容量大小的函數(shù);

我們發(fā)現(xiàn) size() 函數(shù)和 length() 函數(shù)的返回值其實是一樣的;

這是因為c++中,其他容器中的檢查容量大小的函數(shù)都是 size() ,因此又引入了 size() 函數(shù);?

此外,我們發(fā)現(xiàn) capacity() 函數(shù)的返回值和其他兩個函數(shù)不一樣,這是由string類的實現(xiàn)形成的;

string類的實現(xiàn)可以看做是一個char類型的指針(實際上比這更復(fù)雜一點,但是為了好理解可以視為是char類型的指針),并且內(nèi)部除了 char* 指針,還有一個 size 和 capacity 變量;

而它們?nèi)叩年P(guān)系類似下圖:?

實際上string對象開辟的大小為 capacity 這么大,而內(nèi)部存儲的字符串大小為size大??;

這就是為什么兩個函數(shù)返回值不同的原因;

而 clear() 函數(shù)和empty()函數(shù)只在乎size()的大?。?/p>

而 size 和 capacity 的大小也是有成員變量可以修改的;

reserve(size_t n) / resize(size_t n, char c) 函數(shù)

這兩個函數(shù)都是針對 capacity 變量和 size 變量而出現(xiàn)的函數(shù);

我們先看看 resize 函數(shù);

void test5()
{
	string s1 = "hello world!";
	cout<<"s1.size:"<< s1.size()<<' '<<"s1.capacity:"<

我們發(fā)現(xiàn),resize() 更改了有效字符的長度,而 capacity 并未改變;

并且就算我們將 size 改回原來的長度,也無法恢復(fù)原來的數(shù)據(jù);

而 reserve() 函數(shù)則不用多說,自然是修改 capacity 的大小了,但是它改變得比較奇怪;

void test7()
{
	string s1 = "hello world!";
	cout<< "s1.capacity : "<< s1.capacity()<< ' '<< s1<< endl;
	s1.reserve(20);
	cout<< "s1.capacity : "<< s1.capacity()<< ' '<< s1<< endl;
	s1.reserve(10);
	cout<< "s1.capacity : "<< s1.capacity()<< ' '<< s1<< endl;


}

我們發(fā)現(xiàn),命名我們用 reserve 函數(shù)將 capacity 更改到20,但是實際上它的大小為31;

而更改到10則沒變化;

這是為什么呢?

我們先去官網(wǎng)上看看reserve函數(shù)的描述:

大致意思是:

如果 n 比string 的capacity 大,那么編譯器就會擴大容器的大小到 n 或者更大,而其他情況下,就根據(jù)容器的實現(xiàn)進行優(yōu)化;

也就是說,reserve 函數(shù)并非根據(jù)你輸入的數(shù)據(jù)來擴大容量,而是根據(jù)編譯器內(nèi)部的實現(xiàn)來進行擴大;

因此這就是為什么我們擴大到20的時候,會擴大到31;

而至于為什么我們想要縮小到10的時候,則沒變呢?

雖然官網(wǎng)描述中說自由優(yōu)化,實際上大部分編譯器的實現(xiàn)當 n 小于 capacity 的時候,并不會對capacity 進行修改;

此外,官網(wǎng)的描述中,規(guī)定這個函數(shù)不會影響字符串的內(nèi)容,因此當 n 小于 capacity 的時候就不作修改了;

string類對象的訪問及遍歷操作
函數(shù)名稱 功能
operator[] (size_t pos)返回 pos 位置的字符
begin()+end()迭代器訪問
rbegin()+end()反向迭代器訪問
范圍forc++支持的新型for循環(huán)訪問

通過之前的實踐,我們都知道 string 類對象都可以直接通過 cout 直接輸出;

但是c++還提供了其他方法遍歷 string 類對象;

?operator[] (size_t pos)

首先就是運算符重載的 operator[] 訪問了;

void test8()
{
	string s1 = "hello world!";
	for (int i = 0; i< s1.size(); i++)
	{
		cout<< s1[i];
	}
	cout<< endl;
}

這種訪問方式就和 c 語言中訪問字符數(shù)組一樣了;

而這樣的訪問方式實際上是在類內(nèi)部實現(xiàn)的;

begin()/end()/rbegin()/rend()

c++中有各種各樣的容器,由于底層結(jié)構(gòu)不同,所以各種容器的訪問方式也不同;

但是c++為了保證容器的統(tǒng)一性,而創(chuàng)造出了迭代器——iterator,來保證容器訪問方式的一致性;

迭代器——iterator

每個容器里面都有 iterator ,它是一個類似于指針的東西,用戶通過迭代器能夠訪問容器的內(nèi)容;

而每一個容器的 begin() 和 end() 函數(shù)都是為迭代器服務(wù)的;

接下來我們看看迭代器的使用方式吧!

void test9()
{
	string s1 = "hello world!";
	string::iterator is1 = s1.begin();

	while (is1 != s1.end())
	{
		cout<< *is1;
		is1++;
	}
	cout<< endl;

}

迭代器并非通過下標訪問那樣,只用比較 i 和 size 之間的大??;

迭代器只能通過和容器內(nèi)部的 end() 返回值來比較,看是否到達變量的尾部;

并且,迭代器也有 const 類型的迭代器,用于被 const 修飾容器變量;

void test9()
{
	const string s1 = "hello world!";
	string::const_iterator is1 = s1.begin();

	while (is1 != s1.end())
	{
		cout<< *is1;
		is1++;
	}
	cout<< endl;

}

rbegin() 和 rend()

前面說過,這兩個函數(shù)屬于反向迭代器,而它的用法和普通迭代器一模一樣;

void test9()
{
	string s1 = "hello world!";
	string::reverse_iterator is1 = s1.rbegin();

	while (is1 != s1.rend())
	{
		cout<< *is1;
		is1++;
	}
	cout<

通過反向迭代器,我們能夠反向遍歷容器內(nèi)容的內(nèi)容,其使用方式和普通迭代器是一樣的;

范圍for

范圍for應(yīng)該算是比較通用的,就不用過多講解了;

void test9()
{
	string s1 = "hello world!";
	string::reverse_iterator is1 = s1.rbegin();

	for (auto e : s1)
	{
		cout<< e;
	}
	cout<

string類對象修改操作
函數(shù)名功能
push_back(char c)在字符串后面添加c
append()? ? //有多種重載在字符串后面追加字符串
operator+=在字符串后面追加字符串str
c_str()返回c格式字符串
find()+npos在pos位置往后找字符c,并返回所在位置
rfind()在pos位置往前找字符c,并返回所在位置
erase()刪除對應(yīng)位置的元素,并且返回該元素的下一個位置
substr在 str 中從pos位置截取 n 個字符,并返回

push_back(char c)

這個函數(shù)一次只能在字符串尾端放一個字符;

可以直接放,也能夠放char類型的變量;

void test10()
{
	string s1 = "hello world!";
	char a = 'a';
	cout<< s1<< endl;
	s1.push_back('!');
	s1.push_back('!');
	s1.push_back('!');
	s1.push_back('!');
	s1.push_back(a);

	cout<< s1<< endl;
}

這里可以看到成功的在尾端放入了字符;

append(const char * s)

append(const char* s ,size_t n)

append(const string & s)

append(const string& s,size_t subpos,size_t sublen);

append(size_t n ,char c)

template
append(InputIterator first,InputIterator last)

append這個函數(shù)有比較多的重載,接下來我們看看這些重載都是怎么用的吧:

void test10()
{
	string s1 = "hello world!";
	cout<< s1<< endl;
	//append(const char * s)
	s1.append("!!!");//添加!?。〉絪1尾部
	cout<< s1<< endl;

	//append(const char* s ,size_t n)
	s1.append("++++++",5);//有6個 +  ,但只加了5個上去
	s1.append("@", 5);//n為5,但是由于字符串只有一個@,因此只加一個@
	cout<< s1<< endl;


	string s2 = "how are you?";
	//append(const string & s)
	s1.append(s2);//將s2添加上去
	cout<< s1<< endl;

	//append(const string& s,size_t subpos,size_t sublen);
	s1.append(s2, 4,3);//在 s2 中從 subpos位置開始添加sublen長度的字符串到s1中
	cout<< s1<< endl;

	//append(size_t n ,char c)
	s1.append(5, '*');//添加n個c到s1中
	cout<< s1<< endl;

	//template//append(InputIterator first,InputIterator last)
	string s3 = "goodbye!";
	s1.append(s3.begin(), s3.begin() + 3);//將s3中從begin()位置開始到begin()+3位置的字符添加到s1中
	cout<< s1<< endl;

}

用法如上

operator+=?

相比于 append ,+= 的重載就比較少;

它的用法就是單純的將 += 右邊的字符串添加到左邊字符串的尾端;

也是比較常用的一種接口;?

void test11()
{
	string s1 = "hello world!";
	s1 += "!!";
	cout<< s1<< endl;

	string s2 = "how are you?";
	s1 += s2;
	cout<< s1<< endl;

	s1 += '#';
	cout<< s1<< endl;
}

const char* c_str() const

c_str()是一個普通的函數(shù),就是返回string對象中的c字符串;

void test11()
{
	string s1 = "hello world!";
	cout<< s1.c_str()<< endl;


}

find(const string& s,size_t pos = 0)

find(const char* s,size_t pos = 0)

find(const char* s,size_t pos,size_t n)

find(char c,size_t pos = 0)

該函數(shù)就是在對象找尋找對應(yīng)字符的位置,并且返回,若是沒找到就會返回-1;

void test11()
{
	string s1 = "hello world!";
	string s2 = " wo";

	//find(const string& s,size_t pos = 0)
	int pos = s1.find(s2);//默認從0位置開始找
	cout<< pos<< endl;

	pos = s1.find(s2, 3);//從3位置開始找
	cout<< pos<< endl;
	
	//find(const char* s,size_t pos = 0)
	pos = s1.find("llo", 0);//從0位置開始找
	cout<< pos<< endl;

	//find(const char* s,size_t pos,size_t n)
	pos = s1.find("ld!",0,5);//從0位置開始找,只找5個位置
	cout<< pos<< endl;

	//find(char c,size_t pos = 0)
	pos = s1.find('d', 0);//從0位置開始找
	cout<< pos<< endl;
}

rfind(const string& s,size_t pos = npos)

rfind(const char* s,size_t pos = npos)

rfind(const char* s,size_t pos,size_t n)

rfind(char c,size_t pos = npos)

rfind?和 find 的使用方式一樣,只不過是向前尋找,就不做多解釋了;

而上面的 npos 實際上就是表示 string 字符串的尾部,因為 rfind 是向前尋找,因此缺省值給的尾部值;

erase(iterator p)

該函數(shù)會刪除p位置的元素,然后將后面的元素一個一個往前移,然后返回p元素的下一個元素的位置;

void test1()
{
	string s1 = "abcd";
	string::iterator is1 = s1.begin();
	is1 = s1.erase(is1);
	cout<< *is1<< endl;
}

當使用erase函數(shù)的時候,若是在erase函數(shù)前面容器擴容了,就會導(dǎo)致迭代器失效

因此需要更新迭代器位置;

substr(size_t pos = 0,size_t? len = npos)

void test12()
{
	string s1 = "hello world!";
	cout<

這個函數(shù)就是在字符串中從 pos 位置截取 len 長度的字符并返回;

不過原字符串不會消失;

string的其他函數(shù)
函數(shù)名功能
operator+將兩個string或者字符串加起來并返回
operator>>整體輸入string類
operator<<整體輸出string類
getline()以行接收string類
relational_operators比較大小

operator+?

void test13()
{
	string s1 = "hello world!";

	cout<< s1<< endl;

	s1 = s1 + "!!!";
	
	cout<< s1<< endl;

}

這是一個運算符重載,返回一個 + 左邊的字符串在前,右邊的字符串在后組合而成的字符串;

當然,它也可以多個字符串相加;

void test13()
{
	string s1 = "hello world!";

	cout<< s1<< endl;

	s1 = s1 + "!!!";
	
	cout<< s1<< endl;

	s1 = "!!!" + s1 + "!!!";
	cout<< s1<< endl;

}

operator>>/ operator<<

這兩個其實在前面就已經(jīng)用過多次了:

void test13()
{
	string s1;
	cin >>s1;
	cout<< s1;

}

其中的 operator>>和普通的輸入一樣,遇見空格或者換行就會中斷,如上圖;

getline(istream& in,string& s,char delim)

getline(istream& in,string& s)

為了能夠按行輸入string,c++有 getline 函數(shù);

一種形式是遇到和 delim 相同的字符就停止

void test13()
{
	string s1;
	//getline(istream& in,string& s,char delim)
	getline(cin, s1,'o');//按行接收字符串,遇到delim就結(jié)束,這里遇到o就不接收
	cout<< s1<< endl;

}

一種解釋單純的按行接收

void test13()
{
	string s1;
	//getline(istream& in,string& s)
	getline(cin, s1);//按行接收字符串
	cout<< s1<< endl;

}

以上就是string類常用的幾種函數(shù)。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


分享名稱:C++string類-創(chuàng)新互聯(lián)
文章地址:http://weahome.cn/article/igids.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部