1. 程式人生 > >c++ 中的 string 類

c++ 中的 string 類

c++ 中string類的學習


1. string類的建構函式


建構函式 描述
string(const char *s) 將string物件初始化為s指向的NBTS(表示以空字元結束的字串)
string(size_type n,char c) 建立一個大小為n的string物件,並且每個元素都被初始化為字元c
string(const string & str) 將一個string物件初始化為string物件str(複製建構函式)
string() 建立一個預設的string物件,長度為 0 (預設的建構函式)
string(const char * s,size_type n) 將string物件初始化為s的前n個字元,即使超過了結尾
template< class Iter> , string(Iter begin,Iter end) 將string物件初始化為區間[begin ,end)內的字元,begin,end的行為就像指標
string(const string & str, size_type pos=0,size_type n=npos) 將string物件初始化為str從pos開始的n個字元
string(string && str) C++ 11 新增,將一個string物件初始化為string 物件 str.
string(initializer_list< char> il) C++ 11 新增,將string物件初始化為初始化列表 il 中的字元

開始做一下練習:

#include <iostream>

#include <cstring>

//using string constructors
using namespace std;

int main()
{
    string one("hello world!");     //ctor # 1
    cout << one << endl;
    string two(20, '&');            //ctor #2
    cout << two << endl;
    string three(one);             //ctor #3
    cout << three <<endl;
    one += "  what!";             //overloaded +=
    cout << one << endl;
    two = "sorry, that is";
    three[0] = 'H';
    string four;                   //ctor #4
    four = two + three;            //overloaded  +  =
    cout << four << endl;
    char alls[] = "All is well that ends well";
    string five(alls, 20);            //ctor #5
    cout << five << endl;
    string six(alls+6, alls+20);      //ctor # 6
    cout << six << endl;
    string seven(&five[6],&five[20]);    // ctor #6 again
    cout << seven << endl;
    string eight(four, 7, 13);       //ctor #8
    cout << eight << endl;

    return 0;
}

結果如下:
在這裡插入圖片描述

建構函式記住常用的幾個即可,做題的時候可以成為一種工具!!!!

2. string物件的輸入


2.1對於c-風格字串,有3種方式:

char info[100];
cin >> info; //read a word
cin.getline(info, 100); //read a line, discard \n
cin.get(info , 100); //read a line, leave \n in queue

2.2 對於string物件,有兩種方式

string stuff;
cin >> stuff ; //read a word;
getline(cin ,stuff); //read a line, discard \n

string版本的getline()將自動調整string物件的大小,使之剛好能夠儲存輸入的字元。

具體分析cin、 cin.getline() 、 getline() 的用法區別,參考:
https://blog.csdn.net/qq_22613757/article/details/83792747

注: cin.get() cin.getline()區別
分為三種情況來看:
1)輸入的字串不超過限定大小
get(str,Size):讀取所有字元,遇到’\n’時止,並且將’\n’留在輸入緩衝區中,其將被下一個讀取輸入的操作捕獲,影響該輸入處理;
getline(str,Size):讀取所有字元,遇到’\n’時止,並且將’\n’直接從輸入緩衝區中刪除掉,不會影響下面的輸入處理。

2)輸入的字元數超出限定的大小
get(str,Size):讀取Size-1個字元,並將str[Size-1]置為’\0’,然後將剩餘字元(包括’\n’)留在輸入緩衝區中,這些字元將被下一個讀取輸入的操作捕獲,影響該輸入處理;
getline(str,Size):讀取Size-1個字元,並將str[Size-1]置為’\0’,剩餘字元(包括’\n’)留在輸入緩衝區中,隨即設定cin實效位(即if(!cin)的判斷為真),關閉輸入。其後的所有輸入都無法得到任何東西,當然也無法得到輸入緩衝區中剩餘的字串。但如果象本例一樣用clear()重置cin,其後的輸入便可用並會得到遺留在輸入緩衝區中的字元。

3)輸入一個空行(即直接回車)
get(str,Size):str將得到’\0’,並設定cin實效位,關閉輸入,但回車依然留在輸入緩衝區中,因此如果我們用clear()重置cin,其下一個讀取輸入的操作將捕獲’\n’;
getline(str,Size):str將得到’\0’,並將’\n’刪除掉,不置實效位,不關閉輸入。所以對於cin.getline來說空行是合法的輸入,且不會影響下面的輸入處理。

至於使用那個更好,可能因人習慣不同而不同,仁者見仁智者見智。對於我們程式設計來說,總希望能有更好的容錯性,即便使用者輸入了不合理的輸入,程式也應該能夠 提示並能夠重新輸入或繼續正常處理,而因為使用者的輸入問題而導致程式錯誤或其後的所有輸入都不可用顯然不是我們希望的。使用get(str,Size)和 getline(str,Size),都可能碰到設定失效位,關閉輸入的情況,故都是需要考慮到相應的防錯處理的。

2.3 string物件讀取檔案

用於string物件的輸入函式使用輸入流,能夠識別檔案尾,因此也可以使用它們從檔案中讀取輸入。例:

#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;

int main()
{
   /**讀檔案*/
    ifstream fin;
    fin.open("tobuy.txt");
    if(fin.is_open() == false)
    {
        cerr << "Can't open file, bye!\n";
        exit(EXIT_FAILURE);
    }
    string item;
    int count = 0;;
    getline(fin, item, ':');
    while(fin)
    {
        ++count;
        cout << count << ":" << item << endl;
        getline(fin, item, ':');
    }
    cout << "done\n";
    fin.close();

    return 0;
}

檔案內容:
在這裡插入圖片描述
結果:
在這裡插入圖片描述
使用:定為分界字元後,換行符將被視為常規字元。因此檔案中第一行末尾的 換行符將成為包含“wozhendel”的字串的第一個字元。

3. string 物件的使用


除了以上介紹的所有操作外,string類物件還可以進行很多其他操作:

  1. 比較字串
    string 類對6個關係運算符都進行了過載,可以進行大小的比較。
    對於每個關係運算符,都以三種方式進行過載,以便能夠將string物件與另一個string物件,C-風格字串進行比較,並能夠將C-風格字串與string物件進行比較:
    string snake1(“cobra”);
    string snake2(“cora1”);
    char snake3[20] = “anaconda”;
    if(snake1 < snake2) // operator<(const string &,const string &)

    if(snake1 == snake3 ) // operator = = (const string &,const char *)

    if(snake3 != snake2) // operator != (const char *, const string &)
  2. size()和length()函式
  3. find()方法
方法原型 描述
size_type find(const string &str, size_type pos=0)const 從字串的pos位置開始,查詢子字串str。如果找到,則返回子字串第一次出現時首字元的索引,否則,返回str::npos
size_type find(const char * s, size_type pos=0)const 從字串的pos位置開始,查詢子字串str,如果找到,則返回子字串第一次出現時首字元的索引,否則,返回,str::npos
size_type find(const char *s, size_type pos = 0,size_type n) 從字串的pos位置開始,查詢s的前n個字元組成的子字串。如果找到,則返回該子字串首次出現時其首字元的索引;否則,返回 string::npos
size_type find(char ch,size_type pos =0) const 從字串的pos位置開始,查詢字元ch。如果字元ch。如果找到,則返回該字元首次出現的位置,否則,返回 string::npos

string 庫還提供相關方法: rfind()、find_first_of()、find_last_of()、find_first_not_of()和find_last_not_of(),它們在過載函式特徵都與find()方法相同,rfind()查詢子字串或字元最後一次出現的位置,find_fist_of()方法在字串查詢引數中任何一個字元首次出現的位置。find_last_of()相似。find_first_not_of()查詢字串中查詢第一次不包含引數出現的位置。同理find_last_not_of().

capacity()返回當前分配給字串的記憶體塊的大小;
reserve() 方法返回能夠請求記憶體塊的最小長度;

如果有string物件,但需要C-風格字串,該如何辦:
例如:

string filename;
cin >> filename;
ofstream fout;

open()方法要求使用一個C-風格字串作為引數,幸運的是,c_str()方法返回一個指向C-風格字串指標。
fout.open(filename.c_str());