替换 C 中字符串中所有出现的子字符串
Replace all occurrences of a substring in a string in C
我正在尝试用 C 编写一个函数来替换字符串中出现的所有子字符串。我做了我的函数,但它只适用于较大字符串中第一次出现的子字符串。
目前的代码如下:
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] = '[=10=]'; //EDIT: THIS WAS MISSING
strcat(buffer, replace);
strcat(buffer, p+strlen(search));
strcpy(string, buffer);
p++;
}
}
我不是 C 编程的新手,但我在这里遗漏了一些东西。
示例:对于输入字符串“marie has apples has”,搜索“has”并替换为“blabla”
第一个“has”替换正确,但第二个“has”替换不正确。
最终输出是“marie blabla apples hasblabla”。注意第二个“有”仍然存在。
我做错了什么? :)
编辑
现在正在工作。添加空终止字符解决了这个问题。
我知道生成的字符串可以大于 100。这是一项学校作业,所以我不会有超过 20 左右的字符串。
初学者:
这一行
strncpy(buffer, string, p-string);
不一定要在复制到 buffer
的内容后附加一个 0
终止符。
下面一行
strcat(buffer, replace);
然而依赖于 buffer
被 0
终止。
因为 buffer
还没有被初始化,虽然 0
-终结符很可能错过了后一行,但很可能会超出 buffer
的记忆并由此调用臭名昭著的未定义的行为。
我不太清楚你要遵循什么算法,我觉得这一切都很可疑。最简单的方法可能是:
- 搜索第一次出现的 "needle"(搜索的子字符串)
- 将第一次出现之前的部分复制到结果缓冲区
- 将替换字符串附加到结果缓冲区
- 增加
p
指针,使其指向针后
- 转到 10
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);
}
警告:您还必须小心调用函数的方式。如果替换字符串比针大,修改后的字符串将比原始字符串长,因此您必须确保原始缓冲区足够长以包含修改后的字符串。例如:
char s[1024] = "marie has apples has";
str_replace(s, "has", "blabla");
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] = '[=10=]';
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;
}
输入:玛丽有苹果有
输出: marie blabla apples blabla
我发现需要对功能进行一些必要的更正。
这是新功能
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] = '[=10=]';
strcat(buffer, rep);
//printf("STR:%s\n", buffer);
i = (p - str) + strlen(orig);
}
return buffer;
}
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));
}
我正在尝试用 C 编写一个函数来替换字符串中出现的所有子字符串。我做了我的函数,但它只适用于较大字符串中第一次出现的子字符串。
目前的代码如下:
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] = '[=10=]'; //EDIT: THIS WAS MISSING
strcat(buffer, replace);
strcat(buffer, p+strlen(search));
strcpy(string, buffer);
p++;
}
}
我不是 C 编程的新手,但我在这里遗漏了一些东西。
示例:对于输入字符串“marie has apples has”,搜索“has”并替换为“blabla”
第一个“has”替换正确,但第二个“has”替换不正确。 最终输出是“marie blabla apples hasblabla”。注意第二个“有”仍然存在。
我做错了什么? :)
编辑 现在正在工作。添加空终止字符解决了这个问题。 我知道生成的字符串可以大于 100。这是一项学校作业,所以我不会有超过 20 左右的字符串。
初学者:
这一行
strncpy(buffer, string, p-string);
不一定要在复制到 buffer
的内容后附加一个 0
终止符。
下面一行
strcat(buffer, replace);
然而依赖于 buffer
被 0
终止。
因为 buffer
还没有被初始化,虽然 0
-终结符很可能错过了后一行,但很可能会超出 buffer
的记忆并由此调用臭名昭著的未定义的行为。
我不太清楚你要遵循什么算法,我觉得这一切都很可疑。最简单的方法可能是:
- 搜索第一次出现的 "needle"(搜索的子字符串)
- 将第一次出现之前的部分复制到结果缓冲区
- 将替换字符串附加到结果缓冲区
- 增加
p
指针,使其指向针后 - 转到 10
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);
}
警告:您还必须小心调用函数的方式。如果替换字符串比针大,修改后的字符串将比原始字符串长,因此您必须确保原始缓冲区足够长以包含修改后的字符串。例如:
char s[1024] = "marie has apples has";
str_replace(s, "has", "blabla");
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] = '[=10=]';
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;
}
输入:玛丽有苹果有
输出: marie blabla apples blabla
我发现需要对功能进行一些必要的更正。 这是新功能
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] = '[=10=]';
strcat(buffer, rep);
//printf("STR:%s\n", buffer);
i = (p - str) + strlen(orig);
}
return buffer;
}
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));
}