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

C 語言 strstr + strcpy 刪除子串算法詳解:指針運算與內存移動圖解

     編輯:程式設計疑難解答

代碼片段

while (p = strstr(str1, str2)) {
    strcpy(p, p + len2);
}

場景

  • 原字符串 str1:"this is a dog"
  • 待刪除子串 str2:"is",長度 len2 = 2
  • 目標結果:"th a dog"

逐步執行圖解

初始狀態

str1:  t  h  i  s     i  s     a     d  o  g  \0
index: 0  1  2  3  4  5  6  7  8  9  10 11 12
       ↑           ↑
       p           p+len2 (len2=2)

第一次循環

  1. strstr(str1, "is") 返回指向索引 2 的指針 p(第一個 'i')
  2. p + len2 = p + 2 指向索引 4(第一個 's' 後面的空格)
  3. strcpy(p, p + 2) 執行內存覆蓋:
複製前:  p指向: i  s     i  s     a     d  o  g  \0
           p+2指向:     i  s     a     d  o  g  \0
           
strcpy 逐字節複製:
p[0] = (p+2)[0] → ' ' (空格)
p[1] = (p+2)[1] → 'i'
p[2] = (p+2)[2] → 's'
p[3] = (p+2)[3] → ' '
... 直到 \0

複製後 str1: t  h  [空格] i  s     a     d  o  g  \0
                ↑
                索引2現在是空格,原"is"被覆蓋

第二次循環

  1. strstr 從新字符串開頭搜索,找到索引 4 的 "is"(原第二個)
  2. 同理 strcpy 覆蓋,最終得到 "th a dog"

關鍵點總結

內存視角理解

strcpy(dest, src) 將 src 指向的字符串(含 \0)**逐字節複製**到 dest 指向的內存區域。此處 dest = p(子串開頭),src = p + len2(子串結束後),效果是**將子串後的所有內容向前移動 len2 位**,達到刪除效果。

完整可運行代碼

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

#define SIZE 100

void deleteSubstr(char *str, const char *substr) {
    size_t len = strlen(substr);
    char *p;
    while ((p = strstr(str, substr)) != NULL) {
        strcpy(p, p + len);
    }
}

int main() {
    char str1[SIZE] = "this is a dog";
    char str2[SIZE] = "is";
    
    printf("原始: %s\n", str1);
    deleteSubstr(str1, str2);
    printf("刪除 '%s' 後: %s\n", str2, str1);
    
    return 0;
}

輸出

原始: this is a dog
刪除 'is' 後: th a dog

注意事項

  • ⚠️ **緩衝區安全**:確保 str1 有足夠空間(此處原地修改無擴容風險)
  • ⚠️ **重疊複製**:strcpy 行為未定義當源目重疊,但此處 src > dest 且向前複製,**實際安全**(C 標準庫通常向前複製處理重疊)
  • 💡 **更安全**:用 memmove(p, p + len, strlen(p + len) + 1) 顯式處理重疊
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
表達式含義作用
strstr(str1, str2)查找子串首次出現位置返回指向匹配首字符的指針
len2 = strlen(str2)子串長度計算跳過長度
p + len2指針算術:向後移動 len2 個字節指向子串結束後的下一字符
strcpy(p, p + len2)將源地址內容覆蓋到目標地址實現「刪除」:後續內容前移覆蓋目標子串