Skip to main content

5.2 字串

字串是字元的陣列

字串可以被視為一個字元型別的一維陣列,例如:"Hello world!"在記憶體中是這樣一個一個字元儲存的。

#include <iostream>

using namespace std;

int main()
{
    char greeting[13] = "Hello world!";
    
    cout << greeting;

    return 0;
}

在上圖中最後一個字元 '\0'是什麼呢?這個是所謂的 null字元。因為每個字串的長度是不一定的,cout << greeting; 中,傳給 cout 的其實只是整個字串開頭在記憶體中的位址,cout 會逐個字元輸出,直到遇到 null 字元為止。所以雖然 "Hello world!" 只有 12 個字元長,但是我們準備了長度為 13 的 char 型別陣列來儲存它。

如果我們把程式改成這樣。

#include <iostream>

using namespace std;

int main()
{
    char greeting[13] = "Hello world!";
    
    cout << greeting;  // 輸出: "Hello world!"
    
    cin >> greeting;  // 輸入: "Good"
    
    cout << greeting;  // 輸出: "Good"

    return 0;
}

在第 11 行輸入 "Good" 之後,greeting 陣列的內容會變成這樣。

輸入的字串被存放在 greeting 裡,而且最後被加上一個 null 字元。

如果我們在第 11 行輸入的是 "This_is_a_test_for_a_very_long_string.",想想看會發生什麼事情?

我們輸入的字串會覆蓋掉原來在 greeting 陣列後面的一大堆值。(加底線 _ 是因為 cin 預試讀取到空白或換行字元就會停。)

我們更常用的是 C++ 的 string 型別

如前所述,在不知道別人會輸入多長的資料下,要準備多長的字元陣列才夠?這對系統安全來說是個很重要的問題。

以前在 C 語言裡,我們要想辦法來處理這個問題,而在 C++ 裡現在有一個很方便的字串型別 string 可用。你可以很安全的這樣使用它。(按規矩,需要先 #include <string>才能使用 string。但有的編譯器只要你 #include <iostream> 標頭檔裡,就會include string,所以不寫也有可能會過,但寫了一定不會錯)

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string greeting = "Hello world!";
    
    cout << greeting;  // 輸出: "Hello world!"
    
    cin >> greeting;  // 輸入: "This_is_a_test_for_a_very_long_string."
                      // 很安全,不會覆蓋到其他資料
    cout << greeting;  // 輸出: "This_is_a_test_for_a_very_long_string."
    
    return 0;
}

string 不是 int, float, double, char ...這種原生資料型別(Primitive Data Types)。他是用 C++ 寫出的一個類別(class),所以擁有比原生資料型別更多的能力。

取得 string 字串長度

使用 string 的 length() 方法(method),可以取得 string 內儲存字串的長度。

    string str;
    
    str = "abc";
    cout << str.length() << endl;  // 3
    
    cin >> str;  // 輸入 Memory
    cout << str.length() << endl;  // 6
練習:Reverse - 反向輸出字串

讀取一個不含空白字元的字串,反向輸出它。

例如:

輸入的是範例:

"Hello"

Hello

範例輸出

"olleH"

olleH


要反向輸出字串,我們需要知道該宇串的長度,才能使用索引值,將它一個一個字元反向輸出。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string str;
    
    cin >> str;
    
    for(int i=str.length()-1; i>=0; i--)
    {
        cout << str[i];
    }
    cout << endl;
    
    return 0;
}
Hello olleH
練習:Reverse a string - 反向一個字串

讀取一個不含空白字元的字串,真的將其內容反向 後再輸出。

輸入範例:

Hello

範例輸出:

olleH


#include <iostream>

using namespace std;

int main()
{
    string str;
    
    cin >> str;
    
    cout << "Before reverse: [" << str << "]" << endl;

    int len = str.length();  // length of str
    for(int i=0; i<len/2; i++)
    {
        char ch = str[i];
        str[i] = str[len-i-1];
        str[len-i-1] = ch;
    }

    cout << "After reverse:  [" << str << "]" << endl;

    return 0;
}
Spring Before reverse: [Spring] After reverse: [gnirpS]