首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言實現字串替換:動態分配、雙指針掃描與邊界處理完全指南

     編輯:關於C語言

字串替換(將主串中所有 sub 替換為 rep)是 C 語言指針操作的綜合考驗:動態內存管理、子串匹配、結果構建、邊界條件。本文提供經典實現、逐行註解、測試用例與現代化改進建議。

經典實現:replace 函數

char *replace(char *source, char *sub, char *rep) {
    if (!source || !sub || !rep) return NULL;
    if (*sub == '\0') return strdup(source); // 空子串直接複製

    size_t len_sub = strlen(sub);
    size_t len_rep = strlen(rep);
    size_t len_src = strlen(source);

    // 預估最大可能長度:全匹配且 rep > sub 時
    size_t max_len = (len_rep > len_sub) ? (len_src / len_sub) * len_rep + 1 : len_src + 1;
    char *result = malloc(max_len);
    if (!result) return NULL;

    char *pc1 = result;          // 結果寫入指針
    char *pc2, *pc3;             // 掃描輔助指針

    while (*source) {
        pc2 = source;            // 當前匹配起始
        pc3 = sub;               // 子串掃描

        // 嘗試匹配 sub
        while (*pc2 && *pc3 && *pc2 == *pc3) {
            ++pc2; ++pc3;
        }

        if (*pc3 == '\0') {      // 完全匹配
            pc3 = rep;
            while (*pc3) *pc1++ = *pc3++; // 複製替換串
            source = pc2;        // source 跳過匹配區間
        } else {                 // 不匹配
            *pc1++ = *source++;  // 複製單字元
        }
    }
    *pc1 = '\0';
    return result;               // 調用者負責 free
}

關鍵邏輯圖解

source:  a b b c c d f d c d b b d c d
sub:           d c d
rep:         1 2 3 4 5

掃描到 source[6]='d' 時:
pc2=source+6, pc3=sub
匹配 'd','c','d' 成功 → pc3 走到 '\0'
→ 複製 rep 到 result
→ source = pc2 (指向匹配後第一個字元 'b')
繼續掃描...

測試用例

int main() {
    char s1[] = "abbccdfdcdbbdcd";
    char s2[] = "dcd";
    char s3[] = "12345";
    char *p = replace(s1, s2, s3);
    printf("source=%s\nsub=%s\nreplace=%s\n", s1, s2, p);
    free(p); // 必須釋放
    return 0;
}
// 輸出: abbccf12345f12345bb12345

邊界條件檢查表

輸入預期行為代碼處理
source=NULL返回 NULL開頭判空
sub=""返回 source 副本*sub=='\0' 分支
rep=""刪除所有 sub正常複製空串
sub 不存在返回 source 副本無匹配分支逐字複製
重疊匹配非重疊替換(標準行為)source=pc2 跳過匹配區

現代化改進建議

  1. const 正確性:const char *source, *sub, *rep,僅結果需分配。
  2. 錯誤碼分離:返回 char* 無法區分「分配失敗」與「正常返回空串」,建議改為 int replace(const char*, const char*, const char*, char** out)。
  3. 兩次掃描法:先計算確切所需長度(避免過度分配),再精確構建,減少內存碎片。
  4. 線程安全:無靜態緩衝區,純堆分配,天然線程安全。

改進版簽名(C99)

// 返回 0 成功,-1 分配失敗,-2 參數錯誤
int replace_ex(const char *source, const char *sub, const char *rep, char **out) {
    if (!source || !sub || !rep || !out) return -2;
    if (*sub == '\0') { *out = strdup(source); return *out ? 0 : -1; }
    // ... 兩次掃描實現 ...
}

總結

字串替換看似簡單,實則考驗動態內存規劃、指針狀態機、邊界條件覆蓋。掌握「雙指針匹配 + 結果緩衝區構建」模式,可舉一反三解決字串分割、轉義、模板渲染等眾多文本處理問題。生產代碼請採用改進版簽名,嚴格檢查返回碼並及時 free。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved