[c] C의 문자열에서 부분 문자열을 대체하는 기능은 무엇입니까?

( char *) 문자열이 주어지면 하위 문자열의 모든 항목을 찾아서 대체 문자열로 바꾸고 싶습니다. 나는 이것을 달성하는 간단한 기능을 <string.h>.



답변

최적화 프로그램은 대부분의 지역 변수를 제거해야합니다. tmp 포인터는 strcpy가 null을 찾기 위해 문자열을 걸을 필요가 없는지 확인하기 위해 있습니다. tmp는 각 호출 후 결과의 끝을 가리 킵니다. ( strcpy가 성가신 이유 는 화가의 알고리즘 인 Shlemiel을 참조하십시오 .)

// 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;
}


답변

이것은 표준 C 라이브러리에서 제공되지 않습니다. char * 만 주어지면 교체 문자열이 교체되는 문자열보다 길면 문자열에 할당 된 메모리를 늘릴 수 없기 때문입니다.

std :: string을 사용하면 더 쉽게이 작업을 수행 할 수 있지만, 거기에서도 단일 함수가 수행 할 수는 없습니다.


답변

하나도 없습니다.

strstr 및 strcat 또는 strcpy와 같은 것을 사용하여 직접 롤링해야합니다 .


답변

strstr을 사용하여 부분 문자열을 찾고 strncpy를 사용하여 부분적으로 새 버퍼에 복사하는 자체 교체 함수를 작성할 수 있습니다.

원하는 replace_with길이가 원하는 길이와 같지 replace않으면 새 문자열을 복사 할 새 버퍼를 사용하는 것이 가장 좋습니다.


답변

C의 문자열은 동적으로 성장할 수 없으므로 대체는 일반적으로 작동하지 않습니다. 따라서 대체 할 공간이 충분한 새 문자열을위한 공간을 할당 한 다음 원본 부분과 대체 부분을 새 문자열로 복사해야합니다. 부분을 ​​복사하려면 strncpy를 사용 합니다.


답변

다음은이를 수행하는 몇 가지 샘플 코드입니다.

#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;
}


답변

// 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);
}