C语言 替换 C 中字符串中所有出现的子字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32413667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Replace all occurrences of a substring in a string in C
提问by Erik Blenert
I'm trying to make a function in C to replace all occurrences of a substring in a string. I made my function, but it only works on the first occurrence of the substring in the bigger string.
我正在尝试在 C 中创建一个函数来替换字符串中所有出现的子字符串。我做了我的函数,但它只适用于较大字符串中第一次出现的子字符串。
Here is the code so far:
这是到目前为止的代码:
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] = 'strncpy(buffer, string, p-string);
'; //EDIT: THIS WAS MISSING
strcat(buffer, replace);
strcat(buffer, p+strlen(search));
strcpy(string, buffer);
p++;
}
}
I'm not new to C programming, but I'm missing something here.
我对 C 编程并不陌生,但我在这里遗漏了一些东西。
Example: for input string "marie has apples has", searching for "has" and replace with "blabla"
示例:对于输入字符串“marie has apples has”,搜索“has”并替换为“blabla”
In the first "has" is replaced correctly, but the second one is not. The final output is "marie blabla apples hasblabla". Notice the second "has" is still there.
在第一个“有”被正确替换,但第二个不是。最终输出是“marie blabla apples hasblabla”。注意第二个“有”仍然存在。
What am I doing wrong? :)
我究竟做错了什么?:)
EDIT Is is working now. Adding the null terminating character fixed the problem. I know the resulting string can be bigger than 100. It's a school homework so I won't have strings longer than 20 or so.
编辑现在正在工作。添加空终止字符修复了该问题。我知道生成的字符串可以大于 100。这是学校作业,所以我的字符串不会超过 20 左右。
采纳答案by alk
For starters:
对于初学者:
This line
这条线
strcat(buffer, replace);
not necessarily appends a 0-terminator to what had been copied to buffer.
不一定0在已复制到的内容后附加 -终止符buffer。
The following line
以下行
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);
}
however relies on bufferbeing 0-terminated.
然而依赖于buffer被0终止。
As bufferhad not been initialised and though the 0-terminator most likely misses the latter line may very well read beyond buffer's memory and with this invoke the infamous Undefined Behaviour.
Asbuffer尚未初始化,尽管 -0终止符很可能会错过后一行,但很可能会超出buffer内存的范围,从而调用臭名昭著的未定义行为。
回答by The Paramagnetic Croissant
It doesn't seem clear to me what algorithm you are trying to follow, it all looks fishy to me. What's probably the simplest approach is:
我似乎不清楚您要遵循什么算法,对我来说这一切看起来都很可疑。最简单的方法可能是:
- search for first occurrence of the "needle" (searched-for substring)
- copy the part before the first occurrence to the result buffer
- append the replacement string to the result buffer
- increment the
ppointer so it points just after the needle - GOTO 10
- 搜索第一次出现的“针”(搜索的子字符串)
- 将第一次出现之前的部分复制到结果缓冲区
- 将替换字符串附加到结果缓冲区
- 增加
p指针,使其指向指针之后 - 转到 10
char s[1024] = "marie has apples has";
str_replace(s, "has", "blabla");
Warning:You also have to be careful about how you call your function. If the replacement string is larger than the needle, your modified string will be longer than the original one, so you have to make sure your original buffer is long enough to contain the modified string. E.g.:
警告:您还必须注意如何调用您的函数。如果替换字符串比指针大,则修改后的字符串将比原始字符串长,因此您必须确保原始缓冲区足够长以包含修改后的字符串。例如:
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] = '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));
}
';
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;
}
回答by StackUser
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] = '##代码##';
strcat(buffer, rep);
//printf("STR:%s\n", buffer);
i = (p - str) + strlen(orig);
}
return buffer;
}
Input:marie has apples has
输入:玛丽有苹果有
Output:marie blabla apples blabla
输出:marie blabla 苹果 blabla
回答by Claudio
回答by umesh walkar
i find some needful corrections to be made in function.. here is new function
我发现需要在功能上进行一些必要的更正……这是新功能
##代码##
