1. 程式人生 > >C++ STL string 用法詳解

C++ STL string 用法詳解

一、string的初始化

首先,為了在程式中使用string型別,必須包含標頭檔案 <string>。如下:

   #include <string>

注意這裡不是string.h,string.h是C字串標頭檔案。

string類是一個模板類,位於名字空間std中,通常為方便使用還需要增加:

   using namespace std;

宣告一個字串變數很簡單:

string str;

測試程式碼:

#include <iostream>

#include <string>

using namespace std;

int main ( )

{

    string str;  //定義了一個空字串str

    str = "Hello world";   // 給str賦值為"Hello world"

    char cstr[] = "abcde";  //定義了一個C字串

    string s1(str);       //呼叫複製建構函式生成s1,s1為str的複製品

    cout<<s1<<endl;

    string s2(str,6);     //將str內,開始於位置6的部分當作s2的初值

    cout<<s2<<endl;

    string s3(str,6,3);  //將str內,開始於6且長度頂多為3的部分作為s3的初值

        cout<<s3<<endl;

    string s4(cstr);   //將C字串作為s4的初值

    cout<<s4<<endl;

    string s5(cstr,3);  //將C字串前3個字元作為字串s5的初值。

    cout<<s5<<endl;

    string s6(5,'A');  //生成一個字串,包含5個'A'字元

    cout<<s6<<endl;

    string s7(str.begin(),str.begin()+5); //區間str.begin()和str.begin()+5內的字元作為初值

    cout<<s7<<endl;

    return 0;

}

程式執行結果為:

Hello world

world

wor

abcde

abc

AAAAA

Hello

二、string的比較等操作

你可以用 ==、>、<、>=、<=、和!=比較字串,可以用+或者+=操作符連線兩個字串,並且可以用[]獲取特定的字元。

#include <iostream>

#include <string>

using namespace std;

int main()

{

    string str;

    cout << "Please input your name:"<<endl;

    cin >> str;

    if( str == "Li" )   // 字串相等比較

        cout << "you are Li!"<<endl;

    else if( str != "Wang" )  // 字串不等比較

        cout << "you are not Wang!"<<endl;

    else if( str < "Li")     // 字串小於比較,>、>=、<=類似

        cout << "your name should be ahead of Li"<<endl;

    else

        cout << "your name should be after of Li"<<endl;

    str += ", Welcome!";  // 字串+=

    cout << str<<endl;

    for(int i = 0 ; i < str.size(); i ++)

        cout<<str[i];  // 類似陣列,通過[]獲取特定的字元

    return 0;

}

程式執行結果為:

Please input your name:

Zhang↙

you are not Wang!

Zhang, Welcome!

Zhang, Welcome!

上例中,“ cout<< str[i]; ”可換為: cout<< str.at(i); 

三、string特性描述

可用下列函式來獲得string的一些特性:

int capacity()const;    //返回當前容量(即string中不必增加記憶體即可存放的元素個數)
int max_size()const;    //返回string物件中可存放的最大字串的長度
int size()const;        //返回當前字串的大小
int length()const;       //返回當前字串的長度
bool empty()const;        //當前字串是否為空
void resize(int len,char c);  //把字串當前大小置為len,多去少補,多出的字元c填充不足的部分

測試程式碼:

#include <iostream>

#include <string>

using namespace std;

int main()

{

    string str;

        if (str.empty())

        cout<<"str is NULL."<<endl;

        else

        cout<<"str is not NULL."<<endl;

    str = str + "abcdefg";

    cout<<"str is "<<str<<endl;

        cout<<"str's size is "<<str.size()<<endl;

       cout<<"str's capacity is "<<str.capacity()<<endl;

    cout<<"str's max size is "<<str.max_size()<<endl;

    cout<<"str's length is "<<str.length()<<endl;

    str.resize(20,'c');

    cout<<"str is "<<str<<endl;

    str.resize(5);

    cout<<"str is "<<str<<endl;

    return 0;

}

程式執行結果為:

str is NULL.

str is abcdefg

str's size is 7

str's capacity is 15

str's max size is 4294967294

str's length is 7

str is abcdefgccc

str is abcde

四、string的查詢

由於查詢是使用最為頻繁的功能之一,string提供了非常豐富的查詢函式:(注:string::npos)

size_type find( const basic_string &str, size_type index );  //返回str在字串中第一次出現的位置(從index開始查詢),如果沒找到則返回string::npos
size_type find( const char *str, size_type index );  // 同上
size_type find( const char *str, size_type index, size_type length );  //返回str在字串中第一次出現的位置(從index開始查詢,長度為length),如果沒找到就返回string::npos
size_type find( char ch, size_type index );  // 返回字元ch在字串中第一次出現的位置(從index開始查詢),如果沒找到就返回string::npos

注意:查詢字串a是否包含子串b,不是用 strA.find(strB) > 0 而是 strA.find(strB) != string:npos 這是為什麼呢?(初學者比較容易犯的一個錯誤)

  先看下面的程式碼

int idx = str.find("abc");
if (idx == string::npos);

  上述程式碼中,idx的型別被定義為int,這是錯誤的,即使定義為 unsigned int 也是錯的,它必須定義為 string::size_type。npos 是這樣定義的: static const size_type npos = -1; 因為 string::size_type (由字串配置器 allocator 定義) 描述的是 size,故需為無符號整數型別。因為預設配置器以型別 size_t 作為 size_type,於是 -1 被轉換為無符號整數型別,npos 也就成了該型別的最大無符號值。不過實際數值還是取決於型別 size_type 的實際定義。不幸的是這些最大值都不相同。事實上,(unsigned long)-1 和 (unsigned short)-1 不同(前提是兩者型別大小不同)。因此,比較式 idx == string::npos 中,如果 idx 的值為-1,由於 idx 和字串string::npos 型別不同,比較結果可能得到 false。因此要想判斷 find()等查詢函式的結果是否為npos,最好的辦法是直接比較。

測試程式碼:

執行結果:

#include<iostream>

#include<string>

using namespace std;

int main(){

    int loc;

    string s="study hard and make progress everyday! every day!!";

    loc=s.rfind("make",10);

    cout<<"the word make is at index"<<loc<<endl;//-1表示沒找到

    loc=s.rfind("make");//預設狀態下,從最後一個往前找

    cout<<"the word make is at index"<<loc<<endl;

    loc=s.find_first_of("day");

    cout<<"the word day(first) is at index "<<loc<<endl;

    loc=s.find_first_not_of("study");

    cout<<"the first word not of study is at index"<<loc<<endl;

    loc=s.find_last_of("day");

    cout<<"the last word of day is at index"<<loc<<endl;

    loc=s.find("day");//缺陷狀態下從第一個往後找

    cout<<loc;

    return 0;

} 

 

五、其他常用函式

string &insert(int p,const string &s);  //在p位置插入字串s
string &replace(int p, int n,const char *s); //刪除從p開始的n個字元,然後在p處插入串s
string &erase(int p, int n);  //刪除p開始的n個字元,返回修改後的字串
string substr(int pos = 0,int n = npos) const;  //返回pos開始的n個字元組成的字串
void swap(string &s2);    //交換當前字串與s2的值
string &append(const char *s);   //把字串s連線到當前字串結尾
void push_back(char c)   //當前字串尾部加一個字元c
const char *data()const;   //返回一個非null終止的c字元陣列,data():與c_str()類似,用於string轉const char*其中它返回的陣列是不以空字元終止,
const char *c_str()const;  //返回一個以null終止的c字串,即c_str()函式返回一個指向正規C字串的指標, 內容與本string串相同,用於string轉const char*

測試程式碼:

#include <iostream>

#include <string>

using namespace std;

int main()

{

    string str1 = "abc123defg";

    string str2 = "swap!";

    cout<<str1<<endl;

    cout<<str1.erase(3,3)<<endl;  //從索引3開始的3個字元,即刪除掉了"123"

    cout<<str1.insert(0,"123")<<endl; //在頭部插入

    cout<<str1.append("123")<<endl;   //append()方法可以新增字串

    str1.push_back('A');  //push_back()方法只能新增一個字元

    cout<<str1<<endl;

    cout<<str1.replace(0,3,"hello")<<endl; //即將索引0開始的3個字元替換成"hello"

    cout<<str1.substr(5,7)<<endl; //從索引5開始7個位元組

    str1.swap(str2);

    cout<<str1<<endl;

    const char* p = str.c_str();

    printf("%s\n",p);

    return 0;

}

程式執行結果為:

abc123defg

abcdefg

123abcdefg

123abcdefg123

123abcdefg123A

helloabcdefg123A

abcdefg

swap!

swap!