首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言字串替換:將 "apple" 替換為 "orange" 的多種實現與邊界處理

     編輯:程式設計綜合問答

需求

在字串中查找子串 `"apple"` 並替換為 `"orange"`,原地修改或生成新字串。

方案一:原地替換 (緩衝區足夠大)


void replace_inplace(char *str, const char *oldSub, const char *newSub) {
    char *pos = strstr(str, oldSub);
    if (!pos) return;
    
    size_t oldLen = strlen(oldSub);
    size_t newLen = strlen(newSub);
    size_t tailLen = strlen(pos + oldLen);
    
    if (newLen > oldLen) {
        // 向後移動尾部騰出空間 (需確保緩衝區足夠)
        memmove(pos + newLen, pos + oldLen, tailLen + 1); // +1 複製 \0
    } else {
        // 向前移動或原地覆蓋
        memmove(pos + newLen, pos + oldLen, tailLen + 1);
    }
    memcpy(pos, newSub, newLen);
}

方案二:生成新字串 (安全、無緩衝區溢出風險)


char* replace_new(const char *str, const char *oldSub, const char *newSub) {
    if (!str || !oldSub || !newSub) return NULL;
    size_t oldLen = strlen(oldSub);
    if (oldLen == 0) return strdup(str); // 避免無限循環
    
    // 1. 計算出現次數
    int count = 0;
    const char *tmp = str;
    while ((tmp = strstr(tmp, oldSub))) {
        count++;
        tmp += oldLen;
    }
    if (count == 0) return strdup(str);
    
    // 2. 分配新緩衝區
    size_t newLen = strlen(newSub);
    size_t resultLen = strlen(str) + count * (newLen - oldLen);
    char *result = malloc(resultLen + 1);
    if (!result) return NULL;
    
    // 3. 複製並替換
    char *out = result;
    const char *in = str;
    while (*in) {
        if (strncmp(in, oldSub, oldLen) == 0) {
            memcpy(out, newSub, newLen);
            out += newLen;
            in += oldLen;
        } else {
            *out++ = *in++;
        }
    }
    *out = '\0';
    return result; // 調用者負責 free
}

方案三:C++ std::string (現代 C++ 專案首選)


#include 
std::string replace_cpp(std::string str, const std::string& oldSub, const std::string& newSub) {
    size_t pos = 0;
    while ((pos = str.find(oldSub, pos)) != std::string::npos) {
        str.replace(pos, oldSub.length(), newSub);
        pos += newSub.length(); // 避免重複匹配新插入的內容
    }
    return str;
}

邊界測試案例

輸入oldSubnewSub預期輸出關鍵點
`"apple apple"``"apple"``"orange"``"orange orange"`多次替換
`"pineapple"``"apple"``"orange"``"pinorange"`子串重疊/邊界
`"appapple"``"apple"``"orange"``"apporange"`部分匹配
`""``"a"``"b"``""`空字串
`"aaa"``"aa"``"b"``"ba"`重疊替換策略 (左most優先)

常見坑點

  • `strstr` 返回指針,**指針運算** 必須精確 (`pos + oldLen`)。
  • `memmove` 處理**重疊記憶體** 安全,`memcpy` 不安全。
  • 原地替換**必須確保目標緩衝區足夠大** (分配時預留最大可能增長)。
  • 替換後指針 `in`/`out` 推進邏輯不可出錯,建議大量隨機測試驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved