簡體   English   中英

替換 C 中字符串中所有出現的子字符串

[英]Replace all occurrences of a substring in a string in C

我正在嘗試在 C 中創建一個函數來替換字符串中所有出現的子字符串。 我做了我的函數,但它只適用於較大字符串中第一次出現的子字符串。

這是到目前為止的代碼:

void strreplace(char string*, char search*, char replace*) {
    char buffer[100];
    char *p = string;

    while ((p = strstr(p, search))) {
        strncpy(buffer, string, p-string);
        buffer[p-string] = '\0'; //EDIT: THIS WAS MISSING
        strcat(buffer, replace);
        strcat(buffer, p+strlen(search));
        strcpy(string, buffer);
        p++;
    }
} 

我對 C 編程並不陌生,但我在這里遺漏了一些東西。

示例:對於輸入字符串“marie has apples has”,搜索“has”並替換為“blabla”

在第一個“有”被正確替換,但第二個不是。 最終輸出是“marie blabla apples hasblabla”。 注意第二個“有”仍然存在。

我究竟做錯了什么? :)

編輯現在正在工作。 添加空終止字符修復了該問題。 我知道生成的字符串可以大於 100。這是學校作業,所以我的字符串不會超過 20 左右。

我似乎不清楚您要遵循什么算法,對我來說這一切看起來都很可疑。 最簡單的方法可能是:

  • 搜索第一次出現的“針”(搜索的子字符串)
  • 將第一次出現之前的部分復制到結果緩沖區
  • 將替換字符串附加到結果緩沖區
  • 增加p指針,使其指向指針之后
  • 轉到 10
void str_replace(char *target, const char *needle, const char *replacement)
{
    char buffer[1024] = { 0 };
    char *insert_point = &buffer[0];
    const char *tmp = target;
    size_t needle_len = strlen(needle);
    size_t repl_len = strlen(replacement);

    while (1) {
        const char *p = strstr(tmp, needle);

        // walked past last occurrence of needle; copy remaining part
        if (p == NULL) {
            strcpy(insert_point, tmp);
            break;
        }

        // copy part before needle
        memcpy(insert_point, tmp, p - tmp);
        insert_point += p - tmp;

        // copy replacement string
        memcpy(insert_point, replacement, repl_len);
        insert_point += repl_len;

        // adjust pointers, move on
        tmp = p + needle_len;
    }

    // write altered string back to target
    strcpy(target, buffer);
}

警告:您還必須注意如何調用您的函數。 如果替換字符串比指針大,則修改后的字符串將比原始字符串長,因此您必須確保原始緩沖區足夠長以包含修改后的字符串。 例如:

char s[1024] = "marie has apples has";                         
str_replace(s, "has", "blabla");

對於初學者:

這條線

strncpy(buffer, string, p-string);

不一定在已復制到buffer內容后附加0終止符。

以下行

strcat(buffer, replace);

然而依賴於buffer0終止。

由於buffer尚未初始化,盡管0終止符很可能會錯過后一行,但很可能會讀取buffer內存之外的內容,從而調用臭名昭著的未定義行為。

char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
int i=0;

while(str[i]){
    if (!(p=strstr(str+i,orig)))  return str;
    strncpy(buffer+strlen(buffer),str+i,(p-str)-i);
    buffer[p-str] = '\0';
    strcat(buffer,rep);
    printf("STR:%s\n",buffer);
    i=(p-str)+strlen(orig);
}

return buffer;
}

int main(void)
{
  char str[100],str1[50],str2[50];
  printf("Enter a one line string..\n");
  gets(str);
  printf("Enter the sub string to be replaced..\n");
  gets(str1);
  printf("Enter the replacing string....\n");
  gets(str2);
  puts(replace_str(str, str1, str2));

  return 0;
}

輸入:瑪麗有蘋果有

輸出: marie blabla 蘋果 blabla

int replace_str(char* i_str, char* i_orig, char* i_rep)
{
   char l_before[2024];
   char l_after[2024];
   char* l_p;
   int l_origLen;

   l_origLen = strlen(i_orig);
   while (l_p = strstr(i_str, i_orig)) {
      sprintf(l_before ,"%.*s" ,l_p - i_str ,i_str);
      sprintf(l_after ,"%s" ,l_p + l_origLen);
      sprintf(i_str ,"%s%s%s" ,l_before ,i_rep ,l_after);
   }
   return(strlen(i_str));
}

我發現需要在功能上進行一些必要的更正……這是新功能

char *replace_str(char *str, char *orig, char *rep)
{
    static char buffer[1024];
    char *p;
    int i = 0;

    if (!(p = strstr(str + i, orig)))
    {
        return str;
    }

    while (str[i])
    {
        if (!(p = strstr(str + i, orig)))
        {
            strcat(buffer, str + i);
            break; //return str;
        }
        strncpy(buffer + strlen(buffer), str + i, (p - str) - i);
        buffer[p - str] = '\0';
        strcat(buffer, rep);
        //printf("STR:%s\n", buffer);
        i = (p - str) + strlen(orig);
    }

    return buffer;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM