![]() |
奔放的楼房 · PHPWord利用模板替换字符串生成精确的w ...· 1 年前 · |
![]() |
卖萌的佛珠 · 『数据库』震惊,某博主为吸引眼球拿出压箱底S ...· 1 年前 · |
![]() |
文武双全的松鼠 · 如何获取monthCalendar中鼠标选定 ...· 1 年前 · |
![]() |
玩滑板的冲锋衣 · 当实际响应长度与Content-Length ...· 1 年前 · |
![]() |
坏坏的小熊猫 · poi删除word段落_百度知道· 1 年前 · |
给定一个(
char *
)字符串,我希望找到一个子字符串的所有匹配项,并将它们替换为一个备用字符串。我在
<string.h>
中看不到任何简单的函数来实现这一点。
优化器应该消除大多数局部变量。tmp指针用于确保strcpy不必遍历字符串来查找null。tmp在每次调用后指向结果的末尾。(请参阅 Shlemiel the painter's algorithm ,了解为什么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;
}
以下是完成此操作的一些示例代码。
#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);
char * const newstr = replace(argv[1], argv[2], argv[3]);
if (newstr)
printf("%s\n", newstr);
free(newstr);
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);
}
creativeandcritical.net上的 repl_str() 函数快速可靠。该页面还包括一个宽字符串变体 repl_wcs() ,它可以通过助手函数与Unicode字符串一起使用,包括那些以UTF-8编码的字符串-演示代码从页面链接。迟来的全面披露:我是该页面及其功能的作者。
char *replace(const char*instring, const char *old_part, const char *new_part)
#ifndef EXPECTED_REPLACEMENTS
#define EXPECTED_REPLACEMENTS 100
#endif
if(!instring || !old_part || !new_part)
return (char*)NULL;
size_t instring_len=strlen(instring);
size_t new_len=strlen(new_part);
size_t old_len=strlen(old_part);
if(instring_len<old_len || old_len==0)
return (char*)NULL;
const char *in=instring;
const char *found=NULL;
size_t count=0;
size_t out=0;
size_t ax=0;
char *outstring=NULL;
if(new_len> old_len )
size_t Diff=EXPECTED_REPLACEMENTS*(new_len-old_len);
size_t outstring_len=instring_len + Diff;
outstring =(char*) malloc(outstring_len);
if(!outstring){
return (char*)NULL;
while((found = strstr(in, old_part))!=NULL)
if(count==EXPECTED_REPLACEMENTS)
outstring_len+=Diff;
if((outstring=realloc(outstring,outstring_len))==NULL)
return (char*)NULL;
count=0;
ax=found-in;
strncpy(outstring+out,in,ax);
out+=ax;
strncpy(outstring+out,new_part,new_len);
out+=new_len;
in=found+old_len;
count++;
outstring =(char*) malloc(instring_len);
if(!outstring){
return (char*)NULL;
while((found = strstr(in, old_part))!=NULL)
ax=found-in;
strncpy(outstring+out,in,ax);
out+=ax;
strncpy(outstring+out,new_part,new_len);
out+=new_len;
in=found+old_len;
ax=(instring+instring_len)-in;
strncpy(outstring+out,in,ax);
out+=ax;
outstring[out]='\0';
return outstring;
}
我发现大多数提议的函数都很难理解-所以我想出了这个:
static char *dull_replace(const char *in, const char *pattern, const char *by)
size_t outsize = strlen(in) + 1;
// TODO maybe avoid reallocing by counting the non-overlapping occurences of pattern
char *res = malloc(outsize);
// use this to iterate over the output
size_t resoffset = 0;
char *needle;
while (needle = strstr(in, pattern)) {
// copy everything up to the pattern
memcpy(res + resoffset, in, needle - in);
resoffset += needle - in;
// skip the pattern in the input-string
in = needle + strlen(pattern);
// adjust space for replacement
outsize = outsize - strlen(pattern) + strlen(by);
res = realloc(res, outsize);
// copy the pattern
memcpy(res + resoffset, by, strlen(by));
resoffset += strlen(by);
// copy the remaining input
strcpy(res + resoffset, in);
return res;
}
输出必须是空闲的
修复了fann95的响应,使用字符串的就地修改,并假设line指向的缓冲区足够大,可以容纳结果字符串。
static void replacestr(char *line, const char *search, const char *replace)
char *sp;
if ((sp = strstr(line, search)) == NULL) {
return;
int search_len = strlen(search);
int replace_len = strlen(replace);
int tail_len = strlen(sp+search_len);
memmove(sp+replace_len,sp+search_len,tail_len+1);
memcpy(sp, replace, replace_len);
}
您可以使用go....this函数将字符串
str
中出现的所有
char x
替换为
char y
char *zStrrep(char *str, char x, char y){
char *tmp=str;
while(*tmp)
if(*tmp == x)
*tmp++ = y; /* assign first, then incement */
*tmp++;
*tmp='\0';
return str;
}
一个用法示例可以是
Exmaple Usage
char s[]="this is a trial string to test the function.";
char x=' ', y='_';
printf("%s\n",zStrrep(s,x,y));
Example Output
this_is_a_trial_string_to_test_the_function.
该函数来自 string library I maintain on Github ,非常欢迎您查看其他可用函数,甚至对代码做出贡献:)
https://github.com/fnoyanisi/zString
编辑:@siride是对的,上面的函数只替换字符。我刚写了这个,它取代了字符串。
#include <stdio.h>
#include <stdlib.h>
/* replace every occurance of string x with string y */
char *zstring_replace_str(char *str, const char *x, const char *y){
char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y;
int len_str=0, len_y=0, len_x=0;
/* string length */
for(; *tmp_y; ++len_y, ++tmp_y)
for(; *tmp_str; ++len_str, ++tmp_str)
for(; *tmp_x; ++len_x, ++tmp_x)
/* Bounds check */
if (len_y >= len_str)
return str;
/* reset tmp pointers */
tmp_y = y;
tmp_x = x;
for (tmp_str = str ; *tmp_str; ++tmp_str)
if(*tmp_str == *tmp_x) {
/* save tmp_str */
for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){
/* Reached end of x, we got something to replace then!
* Copy y only if there is enough room for it
for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str)
*tmp_str = *tmp_y;
/* reset tmp_x */
tmp_x = x;
return str;
int main()
char s[]="Free software is a matter of liberty, not price.\n"
"To understand the concept, you should think of 'free' \n"
"as in 'free speech', not as in 'free beer'";
printf("%s\n\n",s);
printf("%s\n",zstring_replace_str(s,"ree","XYZ"));
return 0;
}
下面是输出
Free software is a matter of liberty, not price.
To understand the concept, you should think of 'free'
as in 'free speech', not as in 'free beer'
FXYZ software is a matter of liberty, not price.
To understand the concept, you should think of 'fXYZ'
as in 'fXYZ speech', not as in 'fXYZ beer'
您可以使用此函数(注释解释了它的工作原理):
void strreplace(char *string, const char *find, const char *replaceWith){
if(strstr(string, replaceWith) != NULL){
char *temporaryString = malloc(strlen(strstr(string, find) + strlen(find)) + 1);
strcpy(temporaryString, strstr(string, find) + strlen(find)); //Create a string with what's after the replaced part
*strstr(string, find) = '\0'; //Take away the part to replace and the part after it in the initial string
strcat(string, replaceWith); //Concat the first part of the string with the part to replace with
strcat(string, temporaryString); //Concat the first part of the string with the part after the replaced part
free(temporaryString); //Free the memory to avoid memory leaks
}
DWORD ReplaceString(__inout PCHAR source, __in DWORD dwSourceLen, __in const char* pszTextToReplace, __in const char* pszReplaceWith)
DWORD dwRC = NO_ERROR;
PCHAR foundSeq = NULL;
PCHAR restOfString = NULL;
PCHAR searchStart = source;
size_t szReplStrcLen = strlen(pszReplaceWith), szRestOfStringLen = 0, sztextToReplaceLen = strlen(pszTextToReplace), remainingSpace = 0, dwSpaceRequired = 0;
if (strcmp(pszTextToReplace, "") == 0)
dwRC = ERROR_INVALID_PARAMETER;
else if (strcmp(pszTextToReplace, pszReplaceWith) != 0)
foundSeq = strstr(searchStart, pszTextToReplace);
if (foundSeq)
szRestOfStringLen = (strlen(foundSeq) - sztextToReplaceLen) + 1;
remainingSpace = dwSourceLen - (foundSeq - source);
dwSpaceRequired = szReplStrcLen + (szRestOfStringLen);
if (dwSpaceRequired > remainingSpace)
dwRC = ERROR_MORE_DATA;
restOfString = CMNUTIL_calloc(szRestOfStringLen, sizeof(CHAR));
strcpy_s(restOfString, szRestOfStringLen, foundSeq + sztextToReplaceLen);
strcpy_s(foundSeq, remainingSpace, pszReplaceWith);
strcat_s(foundSeq, remainingSpace, restOfString);
CMNUTIL_free(restOfString);
searchStart = foundSeq + szReplStrcLen; //search in the remaining str. (avoid loops when replWith contains textToRepl
} while (foundSeq && dwRC == NO_ERROR);
return dwRC;
}
这就是我的,它是自包含的,多功能的,以及高效的,它在每次递归中根据需要增加或缩小缓冲区
void strreplace(char *src, char *str, char *rep)
char *p = strstr(src, str);
if (p)
int len = strlen(src)+strlen(rep)-strlen(str);
char r[len];
memset(r, 0, len);
if ( p >= src ){
strncpy(r, src, p-src);
r[p-src]='\0';
strncat(r, rep, strlen(rep));
strncat(r, p+strlen(str), p+strlen(str)-src+strlen(src));
strcpy(src, r);
strreplace(p+strlen(rep), str, rep);
}
这是我的,让它们都是char*,这使得呼叫更容易……
char *strrpc(char *str,char *oldstr,char *newstr){
char bstr[strlen(str)];
memset(bstr,0,sizeof(bstr));
int i;
for(i = 0;i < strlen(str);i++){
if(!strncmp(str+i,oldstr,strlen(oldstr))){
strcat(bstr,newstr);
i += strlen(oldstr) - 1;
}else{
strncat(bstr,str + i,1);
strcpy(str,bstr);
return str;
}
仅使用string.h .h中的strlen
对不起,我的英语
char * str_replace(char * text,char * rep, char * repw){//text -> to replace in it | rep -> replace | repw -> replace with
int replen = strlen(rep),repwlen = strlen(repw),count;//some constant variables
for(int i=0;i<strlen(text);i++){//search for the first character from rep in text
if(text[i] == rep[0]){//if it found it
count = 1;//start searching from the next character to avoid repetition
for(int j=1;j<replen;j++){
if(text[i+j] == rep[j]){//see if the next character in text is the same as the next in the rep if not break
count++;
}else{
break;
if(count == replen){//if count equals to the lenght of the rep then we found the word that we want to replace in the text
if(replen < repwlen){
for(int l = strlen(text);l>i;l--){//cuz repwlen greater than replen we need to shift characters to the right to make space for the replacement to fit
text[l+repwlen-replen] = text[l];//shift by repwlen-replen
if(replen > repwlen){
for(int l=i+replen-repwlen;l<strlen(text);l++){//cuz replen greater than repwlen we need to shift the characters to the left
text[l-(replen-repwlen)] = text[l];//shift by replen-repwlen
text[strlen(text)-(replen-repwlen)] = '\0';//get rid of the last unwanted characters
for(int l=0;l<repwlen;l++){//replace rep with repwlen
text[i+l] = repw[l];
if(replen != repwlen){
i+=repwlen-1;//pass to the next character | try text "y" ,rep "y",repw "yy" without this line to understand
return text;
}
如果您希望strlen代码避免调用string.h .h
int strlen(char * string){//use this code to avoid calling string.h
![]() |
坏坏的小熊猫 · poi删除word段落_百度知道 1 年前 |