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

C 語言實現通用字串替換函數:支援全域替換、零庫依賴、記憶體安全

     編輯:關於C語言

需求背景

C 標準庫缺乏字串替換函數,開源實現多僅支援單次替換。本文實現一個全域替換、零標準庫依賴(自製 my_strstr、memcpy)、記憶體安全的 str_replace 函數。

核心子函數實現

1. 子字串查找:my_strstr

/* 回傳:找到→子字串在源字串中的位址;未找到→NULL */
char *my_strstr(char *haystack, char *needle) {
    if (!haystack || !needle) return NULL;
    if (*needle == '\0') return haystack;  // 空字串匹配開頭
    
    char *h = haystack;
    while (*h) {
        char *h1 = h, *n = needle;
        while (*h1 && *n && *h1 == *n) {
            h1++; n++;
        }
        if (*n == '\0') return h;  // 完全匹配
        h++;
    }
    return NULL;
}

2. 記憶體複製:my_memcpy

void *my_memcpy(void *dest, const void *src, size_t n) {
    char *d = (char *)dest;
    const char *s = (const char *)src;
    while (n--) *d++ = *s++;
    return dest;
}

主函數:str_replace

/* 參數:
   result  - 輸出緩衝區(呼叫者保證足夠大)
   source  - 原始字串
   search  - 要被替換的子字串
   replace - 替換字串
   回傳:替換次數
*/
int str_replace(char *result, const char *source, 
                const char *search, const char *replace) {
    if (!result || !source || !search || !replace) return -1;
    if (*search == '\0') return -1;  // 避免無限迴圈
    
    size_t search_len = 0, replace_len = 0;
    const char *p;
    for (p = search; *p; p++) search_len++;
    for (p = replace; *p; p++) replace_len++;
    
    int count = 0;
    const char *src_pos = source;
    char *dst_pos = result;
    
    while (1) {
        char *found = my_strstr((char *)src_pos, (char *)search);
        if (!found) break;  // 無更多匹配
        
        /* 1. 複製匹配點前的內容 */
        size_t prefix_len = found - src_pos;
        my_memcpy(dst_pos, src_pos, prefix_len);
        dst_pos += prefix_len;
        
        /* 2. 複製替換字串 */
        my_memcpy(dst_pos, replace, replace_len);
        dst_pos += replace_len;
        
        /* 3. 移動源位置跳過被替換部分 */
        src_pos = found + search_len;
        count++;
    }
    
    /* 4. 複製剩餘尾部 */
    while (*src_pos) *dst_pos++ = *src_pos++;
    *dst_pos = '\0';
    
    return count;
}

測試驗證

#include <stdio.h>

#define MAX 2000

int main() {
    char source[MAX] = "123123123123";
    char search[] = "23";
    char replace[] = "abcdefg";
    char result[MAX] = {0};
    
    int n = str_replace(result, source, search, replace);
    printf("原始: %s\n", source);
    printf("搜尋: %s\n", search);
    printf("替換: %s\n", replace);
    printf("次數: %d\n", n);
    printf("結果: %s\n", result);
    // 預期: 1abcdefg1abcdefg1abcdefg1abcdefg
    return 0;
}

輸出結果

原始: 123123123123
搜尋: 23
替換: abcdefg
次數: 4
結果: 1abcdefg1abcdefg1abcdefg1abcdefg

關鍵設計決策與權衡

決策點選擇理由
零庫依賴自製 strstr/memcpy嵌入式/核心環境適用;教學價值高
輸出緩衝區由呼叫者分配靜態陣列/動態分配皆可避免函數內 malloc,呼叫者控制生命週期
不修改原字串const source符合函數式風格,線程安全
空搜尋字串保護直接回傳錯誤避免無限迴圈(每個位置都匹配空字串)

效能分析與優化方向

  • 時間複雜度:O(n × m) —— n 為源長度,m 為搜尋長度(朴素匹配)
  • 優化:引入 KMP/BM 演算法將查找降為 O(n+m)
  • 記憶體:單次掃描、原地構建(若 result == source 需額外緩衝)

擴展:支援重疊替換與正則表達式

當前實現不支援重疊匹配(如 "aaa" 替換 "aa" → 僅替換一次)。若需重疊,查找後 src_pos = found + 1 而非 + search_len。正則表達式建議整合 PCRE 或 RE2 庫。

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