C++中的字符串

技術(shù)交流QQ群:1027579432,歡迎你的加入!

1.Cpp中的字符串

  • C++提供了以下兩種類型的字符串表示形式:
    • C風(fēng)格字符串
    • C++引入的string類類型

1.1 C風(fēng)格字符串

  • C風(fēng)格的字符串起源于C語言,并在C++中繼續(xù)得到支持。字符串實際上是使用null字符'\0'終止的一維字符數(shù)組。因此,一個以null結(jié)尾的字符串,包含了組成字符串的字符。
  • 下面的聲明和初始化創(chuàng)建了一個"Hello"字符串。由于在數(shù)組的末尾存儲了空字符,所以字符數(shù)組的大小比單詞"Hello"的字符數(shù)多一個。
        char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    
  • 依據(jù)數(shù)組初始化規(guī)則,可以把上面的語句寫成以下語句:
        char greeting[] = {'H', 'e', 'l', 'l', 'o', '\0'};
    
  • 以下是C/C++中定義的字符串的內(nèi)存表示:


    字符串的在內(nèi)存中的表示.png
  • 其實,不需要把null字符放在字符串常量的末尾。C++編譯器會在初始化數(shù)組時,自動把'\0'放在字符串的末尾,如下面的例子:
        #include "iostream"
    
        using namespace std;
    
        int main(){
            char greeting[6] = {'H', 'e', 'l', 'l', 'o'};
            cout << "greeting: " << greeting << endl;
            return 0;
        }
    
  • C++中有大量的函數(shù)用來操作以null結(jié)尾的字符串,見下表:


    常見字符串函數(shù).png
        // 字符串中的常見函數(shù):
        char str1[11] = "hello";
        char str2[11] = "world";
        char str3[11];
        int len, result;
        // 復(fù)制str1到str3
        strcpy(str3, str1);
        cout << "strcpy(str1, str3):" << str3 << endl;
        // 連接str1和str2
        strcat(str1, str2);
        cout << "strcat(str1, str2):" << str1 << endl;
        // 連接后,str1的總長度
        len = strlen(str1);
        cout << "strlen(str1):" << len << endl;
        // str1與str2比較
        result = strcmp(str1, str2);
        cout << "strcmp(str1, str2):" << result << endl;
    

1.2 C++中的字符串

  • C++標(biāo)準庫提供了string類類型,支持上述所有的操作,另外還增加了其他更多的功能,見下面的實例:
        #include "string"
        // Cpp中的字符串
        string s1 = "abandon";
        string s2 = "banana";
        string s3;
        // 復(fù)制s1到s3
        s3 = s1;
        cout << "s3:" << s3 << endl;
        // 連接s1和s2
        s3 = s1 + s2;
        cout << "s1 + s2:" << s3 << endl;
        // 連接后的s3總長度
        int len1, result1;
        len1 = s3.size();
        cout << "s3.size():" << len1 << endl;
        // 比較s1和s2
        result1 = s1 > s2;
        cout << "s1 > s2:" << result1 << endl;
    

2.字符串中的細節(jié)知識

  • string類提供了一系列針對字符串的操作,比如:
    • append() -- 在字符串的末尾添加字符
    • find() -- 在字符串中查找字符串
    • insert() -- 插入字符
    • length() -- 返回字符串的長度
    • replace() -- 替換字符串
    • substr() -- 返回某個子字符串
    // 4 string類中的其他函數(shù)
        string name = "Curry";
        cout << "The length of string is:" << name.length() << endl;
        // 拼接
        name.append("Coder");
        cout << "name:" << name << endl;
        // 刪除
        int pos;
        pos = name.find("Coder");  // 查找Coder在字符串中的位置
        cout << "pos = " << pos << endl;
        name.replace(pos, 4, "");  // 從位置pos開始,后面的連續(xù)4個字符都將被替換為空格
        cout << "name = " << name << endl;
        // 找子串
        int first = name.find_first_of("r");  // 從頭找到字符r的位置
        int last = name.find_last_of("r");   // 從尾部找字符的位置
        cout << name.substr(first + 1, last - first -1) << endl; // 提取兩個r之間的字符子串
    
  • C++中輸入的方式很多,下面介紹與C語言中g(shù)etchar()類似的函數(shù)cin.getline()函數(shù),cin.getline()是在輸入一段字符完成后開始讀取數(shù)據(jù)(注意,是輸入完成后,以Enter為結(jié)束標(biāo)志)
        // 5 cin.getline()函數(shù)
        char X[N];
        cin.getline(X,N);
        int a = 0, b = 0;
        for (int i=0; i < N;i++){
            if (X[i] == '#')  // #是結(jié)尾標(biāo)志
                break;
            if (X[i] >= '0' && X[i] <= '9')  // 統(tǒng)計數(shù)字個數(shù)
                a++;
            if ((X[i] >= 'a' && X[i] <= 'z') || (X[i] >= 'A' && X[i] <= 'Z')) // 統(tǒng)計字母個數(shù)
                b++;
        }
        cout << "a = " << a << " b = " << b << endl;
    
  • 字符串與vector
    • 字符串常量與標(biāo)準庫string不是同一種類型
          string s("hello");
          cout << "s.size() = " << s.size() << endl;  // 正確
          // cout << "hello".size() << endl;  錯誤
          cout << s + "world" << endl;  // 正確
          // cout << "hello" + "world" << endl;  錯誤
      
    • strlen、sizeof與size()求字符串長度的區(qū)別:
          cout << strlen("123") << endl;   //返回 3
          cout << sizeof("123") << endl;   //返回 4
          string s = "123";
          cout << s.size() << endl;        //返回 3
      
    • sizeof和strlen區(qū)分:
      • sizeof操作符的結(jié)果類型是size_t,它在頭文件中typedef為unsigned int類型。該類型保證能容納實現(xiàn)所建立的最大對象的字節(jié)大小。
      • sizeof是運算符,strlen是函數(shù)
      • sizeof可以用類型做參數(shù),如sizeof(int),strlen只能用char*做參數(shù),且必須是以'\0'結(jié)尾的。sizeof還可以用函數(shù)做參數(shù),如short f(); cout << sizeof(f());
      • 數(shù)組做sizeof的參數(shù)不退化,傳遞給strlen就退化為指針了
      • 大部分編譯程序在編譯的時候就把sizeof計算過了,是類型或是變量的長度,這就是 sizeof(x)可以用來定義數(shù)組維數(shù)的原因。
            char str[20] = "0123456789";
            int a = strlen(str);  10
            int b = sizeof(str);  20
        
      • strlen的結(jié)果要在運行的時候才能計算出來,是用來計算字符串的長度,不是類型占內(nèi)存的大小
      • sizeof后如果是類型必須加括弧,如果是變量名可以不加括弧。這是因為sizeof是個操作符不是個函數(shù)
      • 當(dāng)適用一個結(jié)構(gòu)類型或變量時,sizeof返回實際的大?。划?dāng)適用一靜態(tài)地空間數(shù)組,sizeof 返回全部數(shù)組的尺寸;sizeof操作符不能返回動態(tài)地被分派了的數(shù)組或外部的數(shù)組的尺寸。
    • 字符數(shù)組可以用數(shù)組名來輸出數(shù)組內(nèi)容,而普通數(shù)組不行
      • 原因:因為char型數(shù)組中的每一個元素都是1個字節(jié),所以每一個字符之間的地址都是+1的,是連續(xù)的。所以當(dāng)cou 輸出時讀到字符數(shù)組中的 '\0'便停止輸出; 而int數(shù)組每個元素占4個字節(jié),所以數(shù)組中每個元素地址的間隔是4,但其實它也是連續(xù)的,出現(xiàn)亂碼是因沒找到結(jié)束符。
            int aa[10] = {1, 2, 3, 4, 6, 7};
            char bb[6] = {'h', 'a', 'a', 'p', 'y', '\0'};
            char cc[] = "happy";
            cout << aa << endl;
            cout << bb << endl;
            cout << cc << endl;
        
  • char數(shù)組的幾種表示方法
    • C風(fēng)格
          char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
          char greeting[] = {'H', 'e', 'l', 'l', 'o', '\0'};
      
    • C++風(fēng)格
      • string類
      • char*:指向字符串的指針,指向字符串的首個字母
      • const char*(常量指針):指向的是一個const char類型,不能通過當(dāng)前的指針對字符串的內(nèi)容作修改
      • char * const(指針常量):指針是一個常量,不能修改指針
      • char []:與char*有很多的相同點,代表字符數(shù)組,可以對應(yīng)一個字符串;如char * a = "string1"; char b[] = "string2"; a是一個指向char類型的字符串的指針;b是一個字符數(shù)組
      • char *與char[]的不同:a是變量,指向可以改變;b是常量,是該字符數(shù)組的首地址,其值不能改變

3.注意的地方1

    #include <iostream>
    
    using namespace std;
    
    
    int main(){
        // str1與str2是兩個字符串?dāng)?shù)組,我們會為它們分配長度為12字節(jié)的空間,因為是兩個初始地址不同的數(shù)組,故str1!=str2
        char str1[] = "hello world";
        char str2[] = "hello world";
        if(str1 == str2)
            cout << "str1與str2相同\n";
        else
            cout << "str1與str2不同\n";
        
        // str3 與 str4是兩個指針,無須為它們分配內(nèi)存來存儲字符串的內(nèi)容,只需要把它們指向"hello world"在內(nèi)存中的地址就可以了。
        // 由于"hello world"是字符串常量,它在內(nèi)存中只有一個拷貝,因此str3與str4指向同一個地址
        char *str3 = "hello world";
        char *str4 = "hello world";
        if(str3 == str4)
            cout << "str3與str4相同\n";
        else    
            cout << "str3與str4不同\n";
        return 0;
    }

4.注意的地方2

#include <iostream>
#include <cstring>

using namespace std;

// 數(shù)組中注意的點

int GetSize(char *data){
    return sizeof(data);
}

int GetSize1(char data[]){
    return sizeof(data);
}

int GetSize2(int* data){
    return sizeof(data);
}

int GetSize3(int data[]){
    return sizeof(data);
}

int main(){
    char* ch1 = "abcdefghijk";
    int size11 = sizeof(ch1);
    char* ch11 = ch1;
    int size12 = sizeof(ch11);
    int size13 = GetSize(ch1);
    int size14 = GetSize1(ch1);
/*---------------------------------------------------------------*/
    char ch2[] = "abcdefghijk";
    int size21 = sizeof(ch2);
    char* ch21 = ch2;
    int size22 = sizeof(ch21);
    int size23 = GetSize(ch2);
    int size24 = GetSize1(ch2);
/*---------------------------------------------------------------*/
    int data[] = {1, 2, 3, 4, 5};
    int size31 = sizeof(data);
    int* data11 = data;
    int size32 = sizeof(data11);
    int size33 = GetSize2(data);
    int size34 = GetSize3(data); 
/*---------------------------------------------------------------*/
    cout << "size11 = " << size11 << endl;
    cout << "size12 = " << size12 << endl;
    cout << "size13 = " << size13 << endl;
    cout << "size14 = " << size14 << endl;
/*---------------------------------------------------------------*/
    cout << "size21 = " << size21 << endl;
    cout << "size22 = " << size22 << endl;
    cout << "size23 = " << size23 << endl;
    cout << "size24 = " << size24 << endl;
/*---------------------------------------------------------------*/
    cout << "size31 = " << size31 << endl;
    cout << "size32 = " << size32 << endl;
    cout << "size33 = " << size33 << endl;
    cout << "size34 = " << size34 << endl;
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容