c++string類成員函式
技術標籤:c++
c++在c語言的基礎上擴充套件了對於字串的支援,使其使用方式更加多樣化,使用者可以根據實際需要選擇最佳的使用方式,具有更強的可操作性。
c++繼承了c語言中的c風格字串,並開發出了內建的string類。c語言標準函式庫中提供了大量的函式用來操作以’\0’結尾的字串,比如strcpy、strlen、strcmp、strcat等。c++繼續支援這些函式,並且在string類中提供了功能與之一樣的成員函式,另外還增加了一些其他的功能。
一.string類建構函式
string類提供了多個建構函式,可以根據資料需要靈活地使用這些函式建立string物件。
- string();
預設建構函式。建立一個預設的string物件,長度為0。
只是宣告但沒有初始化,編譯器會將預設值賦給 s1,預設值是””,即空字串。 - string(const char* s);
將string物件初始化為s指向的字串。
比如:string str = “abcdef”; 將str初始化為字串 ”abcdef” 。
與c風格字串不同,以此方法建立的字串的結尾沒有字串結束符 ’\0’ 。 - string(size_type n, char c);
建立一個包含n個元素的string物件,其中每個元素都被初始化為字元c。
比如:string str = (4, ‘A’); 將str初始化為字串 “AAAA”。 - string(const string & str);
拷貝建構函式。將一個string物件初始化為string物件str(複製構造)。
比如:string a(“abcd”); //將a初始化為字串”abcd”
string b(a); //將b初始化為和a一樣,即b也是字串”abcd” - string(const char *s, size_type n);
將string物件初始化為s指向的字串的前n個字元。
比如:string a(5, ‘X’); //將a初始化為字串”XXXXX”
string b(a, 3); //將b初始化為字串a的前3個字元,即”XXX”
使用該方法具有一定的風險性,如果n超過了s指向的字串的長度,會導致一些無用的字元也被賦給該string物件。讀者不妨將string b(a, 3)改為string b(a, 2000); 進行對比。 - string(const string &str, string size_type pos=0, size_type n=npos);
將string物件初始化為引數str指向的字串中的一連串字元。這一連串字元是從下標為pos的字元開始的n個字元。如果從下標為pos的字元開始算起,str指向的字串沒有n個字元,那麼就會使用該字串從下標為pos的字元到結尾的所有字元將string物件初始化。
比如:string a(“abcdef”); //將a初始化為字串”abcdef”
string b(a, 2, 3); //將b初始化為字串”cde”
string c(a, 2, 10); //長度溢位,只會將c初始化為”cdef”
cout<<”a[0] = ”<<a[0]<<endl; //a[0] = a
cout<<”c[3] = ”<<c[3]<<endl; //c[3] = f
string物件可以像使用字元陣列一樣通過下標訪問到每一個元素(即字元),下標同樣是從0開始,但是string物件最後面沒有字串結束符 ’\0’ 。 - tempaltestring(Iter begin, Iter end);
和第6點的用法相似,也是使用另一個字串中的一連串字元來初始化string物件。區別是Iter begin和Iter end分別指定了這一連串字元的起始地址和結束地址,但是隻包括Iter begin,不包括Iter end。
比如:string a(“abcdef”); //將a初始化為字串”abcdef”
string b(a+1, a+5); //錯誤,a是一個string類物件,不是指標,a+1沒有意義
string c(&(a[1]), &a[5]); //將c初始化為字串 ’bcde’,而不是’bcdef’
或者這樣:const char* a = “abcedf”; //此時a是一個指標,表示的是地址,對它進行 + 操作是合理的。
string b(a+1, a+5); //將b初始化為字串 ’bcde’ 。
二.string物件的賦值
- 直接賦值
可以使用char*型別的常量、變數,char型別的常量、變數對string物件進行賦值
#include<iostream>
#include<string>
using namespace std;
int main()
{
char a[10] = "2";
char* a1 = a;
string str = a1; //char*型變數對string物件賦值
cout << "str = " << str << " str.size() = " << str.size() << endl;
const char* a2 = "abcd";
str = a2; //char*型常量對string物件賦值
cout << "str = " << str << " str.size() = " << str.size() << endl;
char b1 = 'A';
str = b1; //char型變數對string變數賦值
cout << "str = " << str << " str.size() = " << str.size() << endl;
const char b2 = 'B'; //char型常量對string變數賦值
cout << "str = " << str << " str.size() = " << str.size() << endl;
}
編譯執行結果:
2. 呼叫成員函式assign() 賦值
string 類提供了assign成員函式,可以用來對string 物件賦值。assign 成員函式返回物件自身的引用。assign()的用法與string類的建構函式相同。例如:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str("abcdef"),str1;
str1.assign(str);
str1.assign("aaaa");
str1.assign(str, 2);
str1.assign(5, 'A');
str1.assign(str, 2, 5);
cout << "str1 = " << str1 << " str.size() = " << str1.size() << endl;
}
編譯執行結果:
三.將string物件轉換為c風格字串
string類提供了一個成員函式 c_str() ,該函式使我們能夠將string型別的字串轉換為c風格字串,並返回指向改字串的const指標(const char*)。
對於有些只能對const char*型別進行操作的函式來說,c_str() 提供了極大的方便。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "c風格字串123";
cout<<"strlen of a = "<<strlen(a.c_str())<<endl; //等於14
}
四.計算string型別的字串長度
在上面第三點中,我們使用strlen()函式計算字串str長度時,需要先將string型別的str轉換成const char型別,因為strlen()函式接受一個const char型別的引數。
string類提供了兩個成員函式 size()和length() 。這兩個函式的原始碼除了名稱差異沒有任何不同。length()函式是在string類開發出來的時候就有的,後來c++引入了標準模板庫STL,又加入了size();size()時作為容器的屬性存在,便於符合STL的介面規則。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "c風格字串123";
cout<<"str.size() = "<<str.size()<<endl;
cout<<"str.length() = "<<str.length()<<endl;
cout<<"strlen() of str = "<<strlen(str.c_str())<<endl;
}
編譯執行結果:
五.string物件的比較
與c風格字串一樣,string類的物件之間也可以進行比較,並且比較方式也和c風格字串一樣,即從第一個字元開始,比較其ASCII碼值,如果相等則繼續比較下一個字元,直至最後一個字元。
string類除了使用 <、<=、==、!=、>=、> 這些運算子比較之外,還提供了成員函式compare()用於比較字串大小。該函式返回一個整數來表示比較的結果,如果兩個字串相等,返回0;如果呼叫方法的string物件大於作為引數傳進來的物件,返回1;否則返回 -1。
compare()有多個過載,可用於不同的需求。如下:
- int compare (const basic_string& s) const;
- int compare (const Ch* p) const;
- int compare (size_type pos, size_type n, const basic_string& s) const;
- int compare (size_type pos, size_type n, const basic_string& s,size_type pos2, size_type n2) const;
- int compare (size_type pos, size_type n, const Ch* p, size_type = npos) const;
其中最常用的是第一種:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "c風格字串123";
string str1 = "c風格字串122";
if ( str >= str1 ) //運算子比較兩個string物件
{
if( str.compare(str1)>0 ) //compare()函式比較兩個string物件
{
cout << "hi!" << endl;
cout << str.compare("c風格字串124") << endl; //compare()函式過載比較string物件和c風格字串大小
}
cout << "hi!" << endl;
}
編譯執行結果:
六.string物件的拼接
在c語言中,我們使用strcat()函式來進行字串的拼接,或者使用strcpy()、memcpy()、memccpy()等函式進行字串或者字元陣列的拼接。
有了string類,我們可以直接使用 + 或者 += 運算子來拼接字串。使用 + 來拼接字串時,運算子的兩邊可以都是 string型別的字串,也可以是一個 string型別字串和一個c風格的字串,還可以是一個string型別字串和一個字元陣列,或者是一個string型別字串和一個單獨的字元。例如:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "123";
string str1 = "abc";
char a[4] = "ABC";
char b = 'D';
string total = str + str1 + a + b;
cout << total << endl;
}
編譯執行結果:
此外,string類還提供了一個成員函式append()。該函式可以用來向某個string物件後面新增字串,並返回物件自身的引用。
append()也有多個過載,其用法與建構函式string()和賦值函式assign()相同。例如:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "123";
string total;
total.append(str,0,3);
total.append("abc",0,3);
total.append("ABC");
total.append(1, '$');
cout << total << endl;
}
編譯執行結果和上面使用 + 運算子拼接完全一樣,也是 123abcABC$ 。
七.插入字串
string類提供了一個insert() 成員函式,可以向一個string型別的字串中插入另一個字串,並返回物件自身的引用。
在c語言的字串操作函式中,並不存在向一個字串插入另一字串的函式,前面提到的memcpy()、strcpy()等函式雖然可以從某一個字元開始,向字元陣列或指標指向的字串“插入”字串,但是這種“插入”實際上是一種覆蓋。當然也可以通過臨時變數將後面的字串暫存,在“插入”所需要的字串後再將後面的字串再放到原先的字串中。
儘管上面的方法也能使用c語言實現向字串插入另一字串的操作,但是遠遠沒有直接使用string類的insert()函式來的方便和快捷。
同樣,insert()函式也有多個過載,這裡不再贅述。insert()函式的原型和用法請參考:
http://www.cplusplus.com/reference/string/string/insert/
簡單舉例說明:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "12";
string str1 = "@#$";
str.insert(1,1,'a'); //在下標為 1 的字元前面插入 1 個字元 ‘a’
str.insert(3,"b3c"); //在下標為 3 的字元前面插入字串 “b3c”
str.insert(6,str1); //在下標為 6 的字元前面插入string物件str1
cout << str << endl;
}
編譯執行結果:
八.刪除字串
與第七點插入字串相對的操作,同樣在c語言字串操作函式中不存在這樣的函式。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "1a23456789B0$";
str.erase(1,1);//從str下標為1的字元(即’a’)開始刪除一個字元,得到"123456789B0$"
str.erase(9,3);//從str下標為9的字元(’B’)開始刪除3個字元,得到”123456789”
cout << str << endl;
}
編譯執行結果:
九.交換兩個string物件的內容
同樣是c語言字串操作函式中沒有的,string類提供了一個成員函式swap(),可以用於交換兩個string物件的內容,無返回值。可以將呼叫方法的物件替換為作為引數傳進來的物件,效果是一樣的。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "abc";
string str1 = "ABC";
str1.swap(str);
cout << "str = " << str << endl;
str1.swap(str);
cout << "str = " << str << endl;
}
編譯執行結果: