( 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을 사용하여 부분 문자열을 찾고 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);
}
