在C中替换字符串的功能是什么?

83 c string

给定一个(char*)字符串,我想找到所有出现的子字符串并用替换字符串替换它.我没有看到任何在<string.h>中实现此功能的简单函数

jmu*_*llo 79

优化器应该消除大多数局部变量.tmp指针用于确保strcpy不必遍历字符串以查找null.每次调用后,tmp指向结果的结尾.(请参阅Shlemiel画家的算法,了解为什么strcpy会令人讨厌.)

// You must free the result if result is non-NULL.
char *str_replace(char *orig, char *rep, char *with) {
    char *result; // the return string
    char *ins;    // the next insert point
    char *tmp;    // varies
    int len_rep;  // length of rep (the string to remove)
    int len_with; // length of with (the string to replace rep with)
    int len_front; // distance between rep and end of last rep
    int count;    // number of replacements

    // sanity checks and initialization
    if (!orig || !rep)
        return NULL;
    len_rep = strlen(rep);
    if (len_rep == 0)
        return NULL; // empty rep causes infinite loop during count
    if (!with)
        with = "";
    len_with = strlen(with);

    // count the number of replacements needed
    ins = orig;
    for (count = 0; tmp = strstr(ins, rep); ++count) {
        ins = tmp + len_rep;
    }

    tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);

    if (!result)
        return NULL;

    // first time through the loop, all the variable are set correctly
    // from here on,
    //    tmp points to the end of the result string
    //    ins points to the next occurrence of rep in orig
    //    orig points to the remainder of orig after "end of rep"
    while (count--) {
        ins = strstr(orig, rep);
        len_front = ins - orig;
        tmp = strncpy(tmp, orig, len_front) + len_front;
        tmp = strcpy(tmp, with) + len_with;
        orig += len_front + len_rep; // move to next "end of rep"
    }
    strcpy(tmp, orig);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果没有要替换的出现,则此函数返回 NULL( if (!(ins = strstr(orig, rep))) return NULL; )。您不能只使用输出,您需要检查输出是否为 NULL,如果是,则使用原始字符串(不要只是将指针复制到结果字符串,因为 free(result) 然后释放原始字符串)。如果没有要替换的内容,则将输入字符串直接复制到输出字符串中,使用起来会更直接。 (2认同)

Don*_*eld 18

这在标准C库中没有提供,因为如果替换字符串比要替换的字符串长,则只给出char*,不能增加分配给字符串的内存.

你可以更容易地使用std :: string来做到这一点,但即使在那里,也没有任何一个函数能为你做到这一点.

  • 这个问题是关于C,而不是C++. (8认同)

Bri*_*ndy 8

您可以使用strstr构建自己的替换函数以查找子字符串和strncpy以将部分复制到新缓冲区.

除非您想要replace_with的长度与您想要的长度相同replace,否则最好使用新缓冲区将新字符串复制到.


Ree*_*sey 8

没有一个.

你需要使用像strstr和strcat或strcpy 这样的东西来自己动手.

  • 经常使用的功能的粉丝集合存储在哪里?当然已经有一个图书馆.... (7认同)
  • `strcat()` 是一个糟糕的建议。 (3认同)

lot*_*har 8

由于C中的字符串无法动态增长,因此替换通常不起作用.因此,您需要为具有足够空间进行替换的新字符串分配空间,然后将原始部分和替换部分复制到新字符串中.要复制部件,您将使用strncpy.


ram*_*ion 8

这是一些示例代码.

#include <string.h>
#include <stdlib.h>

char * replace(
    char const * const original, 
    char const * const pattern, 
    char const * const replacement
) {
  size_t const replen = strlen(replacement);
  size_t const patlen = strlen(pattern);
  size_t const orilen = strlen(original);

  size_t patcnt = 0;
  const char * oriptr;
  const char * patloc;

  // find how many times the pattern occurs in the original string
  for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
  {
    patcnt++;
  }

  {
    // allocate memory for the new string
    size_t const retlen = orilen + patcnt * (replen - patlen);
    char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) );

    if (returned != NULL)
    {
      // copy the original string, 
      // replacing all the instances of the pattern
      char * retptr = returned;
      for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
      {
        size_t const skplen = patloc - oriptr;
        // copy the section until the occurence of the pattern
        strncpy(retptr, oriptr, skplen);
        retptr += skplen;
        // copy the replacement 
        strncpy(retptr, replacement, replen);
        retptr += replen;
      }
      // copy the rest of the string.
      strcpy(retptr, oriptr);
    }
    return returned;
  }
}

#include <stdio.h>
int main(int argc, char * argv[])
{
  if (argc != 4)
  {
    fprintf(stderr,"usage: %s <original text> <pattern> <replacement>\n", argv[0]);
    exit(-1);
  }
  else
  {
    char * const newstr = replace(argv[1], argv[2], argv[3]);
    if (newstr)
    {
      printf("%s\n", newstr);
      free(newstr);
    }
    else
    {
      fprintf(stderr,"allocation error\n");
      exit(-2);
    }
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)


Ruc*_*nga 5

// Here is the code for unicode strings!


int mystrstr(wchar_t *txt1,wchar_t *txt2)
{
    wchar_t *posstr=wcsstr(txt1,txt2);
    if(posstr!=NULL)
    {
        return (posstr-txt1);
    }else
    {
        return -1;
    }
}

// assume: supplied buff is enough to hold generated text
void StringReplace(wchar_t *buff,wchar_t *txt1,wchar_t *txt2)
{
    wchar_t *tmp;
    wchar_t *nextStr;
    int pos;

    tmp=wcsdup(buff);

    pos=mystrstr(tmp,txt1);
    if(pos!=-1)
    {
        buff[0]=0;
        wcsncpy(buff,tmp,pos);
        buff[pos]=0;

        wcscat(buff,txt2);

        nextStr=tmp+pos+wcslen(txt1);

        while(wcslen(nextStr)!=0)
        {
            pos=mystrstr(nextStr,txt1);

            if(pos==-1)
            {
                wcscat(buff,nextStr);
                break;
            }

            wcsncat(buff,nextStr,pos);
            wcscat(buff,txt2);

            nextStr=nextStr+pos+wcslen(txt1);   
        }
    }

    free(tmp);
}
Run Code Online (Sandbox Code Playgroud)