我将忽略删除的代码,<>
只关注问题的核心。
如果您事先不知道字符串和替换的长度,那么您有几个选择:
- 首先计算匹配的数量并使用它来计算所需的空间
- 在循环中使用
realloc
以更改分配的内存量
- 从对大小的智能猜测开始,然后根据需要使用 realloc
- 使用固定大小的缓冲区,如果我们用完就会出错
第一种是最简单的方法,您要使用的方法取决于您的性能要求(如果您很好地掌握了最大字符串大小,则四个最快,但会消耗更多内存,如果您掌握了最大字符串大小,则三个可能是下一个最快的对平均匹配次数有一个很好的了解)。
实现最简单的方法只需要两个循环,一个是查找匹配项,一个是替换:
char *strreplace(char *src, char* find, char *repl)
{
char *target; // Will store our new string
char *final; // Will use to store the pointer of the final string
char *str = src; // Will use for searching
int matches = 0;
// First count the matches (if strlen(repl) <= strlen(word)
// you could skip this and just allocate strlen(src)
while (str = strstr(str, find)) {
matches ++;
str++;
}
target = malloc(1 + strlen(src) +
(sizeof(char) * (matches *
(strlen(repl) - strlen(find))
)));
if (target == NULL) {
return src; // Or NULL, or whatever to indicate an error
}
final = target;
// Now copy everything
str = src;
while (str = strstr(str, find)) {
// Copy string before the match
if (str > src) {
strncpy(target, src, (str - src));
target += (str - src);
src += (str - src);
}
// Copy replacement
strncpy(target, repl, strlen(repl));
// Move pointers
str++; // Move past the match in our searching pointer
src += strlen(find); // Move past the string in our src
target += strlen(repl); // Move past the replacement in our target
}
// Finally copy the rest of the string, if there's some left
if (*src) {
strncpy(target, src, strlen(src));
}
return final;
}
我想我可能在那里使用了太多的指针,我觉得可以对替换代码进行简化,但目前我看不到。
您可以采用它并对其进行调整以做您想做的事情,一些测试(尝试覆盖极端情况):
printf("%s\n", strreplace("testtesttest1234", "test", "foo"));
printf("%s\n", strreplace("testtesttest1234", "test", "foobar"));
printf("%s\n", strreplace("somethingtestsomethingteasesttest", "test", "foobar"));
输出:
foofoofoo1234
foobarfoobarfoobar1234
somethingfoobarsomethingteasestfoobar