S SmartDocs
Série: C++ cpp 137 lignes · Mis à jour 2026-04-03

c_strings.cpp

C++/Part1_基礎入門/Ch05_陣列與字串/c_strings.cpp

// ============================================================
// Ch05 — C 風格字串(C-style Strings)
// 編譯:g++ -std=c++17 -Wall -o c_strings c_strings.cpp
// ============================================================

#include <iostream>
#include <cstring>   // strlen, strcpy, strncpy, strcat, strcmp
#include <string>    // std::string(用於轉換示範)

int main() {
    std::cout << "===== Ch05:C 風格字串 =====\n\n";

    // ── 1. 宣告與初始化 ──
    std::cout << "【1】宣告與初始化\n";

    char greeting[] = "Hello";            // 自動加上 '\0',大小為 6
    char name[20] = "C++";               // 預留空間,部分初始化
    char empty[10] = "";                  // 空字串,第一個字元是 '\0'
    char manual[] = {'H', 'i', '\0'};    // 手動加上 '\0'

    std::cout << "greeting = \"" << greeting << "\"\n";
    std::cout << "name     = \"" << name << "\"\n";
    std::cout << "empty    = \"" << empty << "\"\n";
    std::cout << "manual   = \"" << manual << "\"\n";

    // sizeof vs strlen
    std::cout << "\nsizeof(greeting) = " << sizeof(greeting) << "(含 '\\0')\n";
    std::cout << "strlen(greeting) = " << strlen(greeting) << "(不含 '\\0')\n\n";

    // ── 2. strlen — 取得長度 ──
    std::cout << "【2】strlen — 字串長度\n";
    const char* words[] = {"Hello", "C++", "", "世界"};
    for (const char* w : words) {
        std::cout << "strlen(\"" << w << "\") = " << strlen(w) << "\n";
    }
    std::cout << "\n";

    // ── 3. strcpy / strncpy — 複製字串 ──
    std::cout << "【3】strcpy / strncpy — 複製字串\n";

    char dest1[20];
    strcpy(dest1, "Hello, World!");
    std::cout << "strcpy  → \"" << dest1 << "\"\n";

    char dest2[20];
    strncpy(dest2, "Hello, World!", 5);
    dest2[5] = '\0';  // strncpy 不保證加上 '\0',需手動補
    std::cout << "strncpy → \"" << dest2 << "\"(只複製 5 個字元)\n\n";

    // ── 4. strcat — 串接字串 ──
    std::cout << "【4】strcat — 串接字串\n";

    char sentence[50] = "Hello";
    std::cout << "初始:\"" << sentence << "\"\n";

    strcat(sentence, ", ");
    std::cout << "串接 \", \":\"" << sentence << "\"\n";

    strcat(sentence, "World!");
    std::cout << "串接 \"World!\":\"" << sentence << "\"\n\n";

    // ── 5. strcmp — 比較字串 ──
    std::cout << "【5】strcmp — 比較字串\n";

    const char* s1 = "apple";
    const char* s2 = "banana";
    const char* s3 = "apple";

    int result1 = strcmp(s1, s2);
    int result2 = strcmp(s1, s3);
    int result3 = strcmp(s2, s1);

    std::cout << "strcmp(\"apple\", \"banana\") = " << result1;
    std::cout << (result1 < 0 ? "(apple < banana)" : "") << "\n";

    std::cout << "strcmp(\"apple\", \"apple\")  = " << result2;
    std::cout << (result2 == 0 ? "(相同)" : "") << "\n";

    std::cout << "strcmp(\"banana\", \"apple\") = " << result3;
    std::cout << (result3 > 0 ? "(banana > apple)" : "") << "\n\n";

    // ── 6. 字元操作 ──
    std::cout << "【6】字元操作\n";

    char word[] = "Hello";
    std::cout << "原始:\"" << word << "\"\n";
    std::cout << "逐字元輸出:";
    for (int i = 0; word[i] != '\0'; i++) {
        std::cout << word[i] << ' ';
    }
    std::cout << "\n";

    // 轉大寫
    for (int i = 0; word[i] != '\0'; i++) {
        if (word[i] >= 'a' && word[i] <= 'z') {
            word[i] = word[i] - 'a' + 'A';
        }
    }
    std::cout << "轉大寫:\"" << word << "\"\n\n";

    // ── 7. cin.getline — 讀取含空格的輸入 ──
    std::cout << "【7】cin.getline 說明\n";
    std::cout << "cin >> 遇到空格就停止讀取。\n";
    std::cout << "cin.getline(buffer, size) 可讀取整行(含空格)。\n";
    std::cout << "語法:cin.getline(charArray, maxSize);\n\n";

    // 示範(不實際讀取避免阻塞)
    char buffer[100] = "This is a full line";
    std::cout << "假設輸入:\"" << buffer << "\"\n";
    std::cout << "cin.getline 可完整讀取,cin >> 只會讀到 \"This\"\n\n";

    // ── 8. C 字串 ↔ std::string 轉換 ──
    std::cout << "【8】C 字串與 std::string 互相轉換\n";

    // C 字串 → std::string
    const char* cStr = "Hello from C string";
    std::string cppStr = cStr;  // 隱式轉換
    std::cout << "C → std::string: \"" << cppStr << "\"\n";

    // std::string → C 字串
    std::string original = "Hello from std::string";
    const char* converted = original.c_str();
    std::cout << "std::string → C: \"" << converted << "\"\n\n";

    // ── 9. 安全性提醒 ──
    std::cout << "【9】安全性提醒\n";
    std::cout << "⚠ C 風格字串的常見問題:\n";
    std::cout << "  1. 忘記 '\\0' 結尾 → 讀到垃圾記憶體\n";
    std::cout << "  2. strcpy 目標太小 → 緩衝區溢位\n";
    std::cout << "  3. 用 == 比較 → 比的是指標位址,非內容\n";
    std::cout << "  4. 未檢查長度就串接 → 可能溢位\n\n";

    std::cout << "✔ 建議:在新的 C++ 程式中優先使用 std::string。\n";
    std::cout << "  C 字串主要用於與 C 函式庫或系統 API 互動。\n";

    return 0;
}

Articles liés