我有以下代码:
char *repl_word(char *word, char *repl)
{
const char *p1 = strstr(word,"<")+1;
const char *p2 = strstr(p1,">");
size_t len = p2-p1;
char *src = (char*)malloc(len+1);
if (src == NULL)
return word;
strncpy(src,p1,len);
src[len] = '\0';
char *find = "test";
char *found;
char *res = malloc(strlen(src) + strlen(repl) - strlen(find) + 1);
if (res == NULL)
return src;
found = strstr(src, find);
if (found == NULL){
free(res);
return src;
}
res[0] = '\0';
strncpy(res, src, (size_t)(found - src));
strcat(res, repl);
strcat(res, found + strlen(find));
return res;
}
工作正常但仅适用于"test"
的第一次出现。
如果单词是"<testtesttest1234>"
,则它不会替换所有内容。
如何使用repl?
替换字符串中所有出现的test答案 0 :(得分:1)
我将忽略删除<>
的代码,只关注问题的核心。
如果你事先不知道琴弦和替换的长度,那么你有几个选择:
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