字串1

xiaoluosibky發表於2024-11-26

一、字串的基本概念

字串的儲存結構

在 C 語言中,字串本質上是 字元陣列,並以 空字元 \0 結尾。

儲存特點:

  1. 每個字元佔一個位元組
    • 在 ASCII 編碼中,一個字元(如 Aa)佔用 1 個位元組。
    • 一個字串的長度是字元個數加 1(空字元 \0)。
  2. 連續儲存
    • 字元陣列中的每個字元都連續儲存在記憶體中,直到 \0 為止。
  3. 只讀字串
    • 用雙引號定義的字串常量,如 "Hello",通常儲存在只讀記憶體中,無法直接修改。

示例:定義與初始化字串

#include <stdio.h>

int main() {
    char str1[] = "Hello"; // 自動在末尾新增 '\0'
    char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 顯式指定 '\0'

    printf("str1: %s\n", str1); // 輸出 Hello
    printf("str2: %s\n", str2); // 輸出 Hello

    // 錯誤示例(缺少 '\0' 會導致輸出亂碼)
    char str3[] = {'H', 'e', 'l', 'l', 'o'}; 
    printf("str3: %s\n", str3); // 可能輸出 Hello 後接亂碼
    return 0;
}

二、字串的輸入與輸出

示例:字串輸入與輸出

#include <stdio.h>

int main() {
    char name[50];

    // 使用 scanf
    printf("請輸入你的名字:");
    scanf("%s", name); // 以空格或換行符為結束標誌
    printf("Hello, %s!\n", name);

    // 使用 fgets
    printf("請輸入一句話:");
    getchar(); // 清除上次輸入的換行符
    fgets(name, sizeof(name), stdin); // 輸入整行,自動包含換行符
    printf("你輸入的是:%s", name); // 自動輸出換行符

    return 0;
}

注意fgets 讀取的字串會包含換行符,必要時可以手動去掉:

name[strcspn(name, "\n")] = '\0'; // 移除換行符

字串常見錯誤及防範

  1. 未初始化的字串

    • 如果定義了字元陣列但沒有初始化,可能會包含垃圾值。
    char str[10]; // 未初始化
    printf("%s\n", str); // 可能輸出隨機內容
    
  2. 忘記空字元 \0

    • 手動定義字串時,忘記加 \0 會導致錯誤。
    char str[] = {'H', 'e', 'l', 'l', 'o'}; // 缺少 '\0'
    printf("%s\n", str); // 輸出可能會超出預期
    
  3. 陣列越界訪問

    • 超過陣列邊界的訪問會導致不可預知的行為。
    char str[5] = "Test"; 
    str[5] = 'X'; // 錯誤:越界訪問
    

三、字串操作函式

C 標準庫提供了許多操作字串的函式,以下以具體示例講解常用的函式。

1. 字串長度:strlen

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, C!";
    size_t len = strlen(str); // 計算長度
    printf("字串 \"%s\" 的長度是:%lu\n", str, len); // 輸出 9
    return 0;
}

2. 字串複製:strcpystrncpy

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Source";
    char dest[20];

    // 使用 strcpy
    strcpy(dest, src);
    printf("複製結果:%s\n", dest); // 輸出 Source

    // 使用 strncpy
    strncpy(dest, "Example", 3); // 只複製前 3 個字元
    dest[3] = '\0'; // 手動新增 '\0'
    printf("部分複製結果:%s\n", dest); // 輸出 Exa

    return 0;
}

3. 字串連線:strcatstrncat

#include <stdio.h>
#include <string.h>

int main() {
    char str1[50] = "Hello";
    char str2[] = ", World!";

    // 使用 strcat
    strcat(str1, str2); // 拼接字串
    printf("拼接後:%s\n", str1); // 輸出 Hello, World!

    // 使用 strncat
    strncat(str1, " C Programming", 3); // 只拼接前 3 個字元
    printf("部分拼接後:%s\n", str1); // 輸出 Hello, World! C

    return 0;
}

4. 字串比較:strcmpstrncmp

#include <stdio.h>
#include <string.h>

int main() {
    char str1[] = "apple";
    char str2[] = "banana";

    int cmp = strcmp(str1, str2); // 比較字串
    if (cmp < 0)
        printf("\"%s\" 小於 \"%s\"\n", str1, str2);
    else if (cmp > 0)
        printf("\"%s\" 大於 \"%s\"\n", str1, str2);
    else
        printf("\"%s\" 等於 \"%s\"\n", str1, str2);

    // 使用 strncmp
    cmp = strncmp("abcde", "abcfg", 3); // 只比較前 3 個字元
    printf("strncmp 比較結果:%d\n", cmp); // 輸出 0(前 3 個字元相等)

    return 0;
}

5. 字串查詢:strchrstrstr

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";

    // 查詢字元
    char *pos = strchr(str, 'W');
    if (pos)
        printf("找到字元 'W',位置:%ld\n", pos - str);

    // 查詢子串
    char *substr = strstr(str, "World");
    if (substr)
        printf("找到子串 \"World\",起始位置:%ld\n", substr - str);

    return 0;
}

四、綜合練習

示例 1:統計字串中的字元個數

#include <stdio.h>
#include <string.h>

int main() {
    char str[100];
    printf("請輸入一個字串:");
    fgets(str, sizeof(str), stdin);

    // 去掉換行符
    str[strcspn(str, "\n")] = '\0';

    printf("字串 \"%s\" 的長度是:%lu\n", str, strlen(str));
    return 0;
}

示例 2:字串逆序

#include <stdio.h>
#include <string.h>

void reverse(char *str) {
    int len = strlen(str);
    for (int i = 0; i < len / 2; i++) {
        char temp = str[i];
        str[i] = str[len - i - 1];
        str[len - i - 1] = temp;
    }
}

int main() {
    char str[100];
    printf("請輸入一個字串:");
    fgets(str, sizeof(str), stdin);

    // 去掉換行符
    str[strcspn(str, "\n")] = '\0';

    reverse(str);
    printf("逆序後的字串是:%s\n", str);
    return 0;
}

總結

  1. 逐步練習: 先熟悉基本操作(輸入輸出),再學習字串操作函式。
  2. 重點注意: 字串陣列需要足夠的空間,並要防止輸入過長。
  3. 實際應用: 多練習一些常見題目,如字串統計、翻轉、查詢等。

五、字串的實際應用

1. 字串處理

字串在 文字處理加密資料儲存 等場景中非常常見。

示例:統計字串中某個字元出現的次數

#include <stdio.h>
#include <string.h>

int countChar(const char *str, char ch) {
    int count = 0;
    while (*str) {
        if (*str == ch) count++;
        str++;
    }
    return count;
}

int main() {
    char str[100];
    printf("請輸入一個字串:");
    fgets(str, sizeof(str), stdin);

    char ch;
    printf("請輸入要統計的字元:");
    scanf(" %c", &ch);

    printf("字元 '%c' 出現了 %d 次。\n", ch, countChar(str, ch));
    return 0;
}

相關文章