LowestOne:
I tried that, but it gets complicated if substr->size is not equal to repstr->size.
I can easily stretch or contract the string, but to do it the fastest way I'll have to do it the way I've shown in the OP
The function needs to:
if slen > rlen
loop:
find(substr)
replace(substr, otherstring)
end = find(substr) /* again */
if (end == 0) end = end of string;
shift_left(substr.location+substring.length, end);
goto loop
Basically this is what I'm doing with:
1 2 3 4 5 6
|
diff = start - string_write(end, replacement); /* overwrite substring with replacement string */
string = string_find(start, substring); /* find substring */
end = string? string: hstr+len;
string_shift_left(start, end, diff); /* move memory chunk from start to end leftwards */
start = end+substr_length; /* next pick position */
end -= diff; /* next write position */
|
The extra boilerplate is just calculating the difference between the first instance of @substr and the other instance, and making @start and @end ready for next loop iterations.
Of course, I need a different approach entirely for replacing string if replacement size is greater than substring size to make it fastest as possible. For that, basically, we search backwards... or rather, write backwards while extending the string from the end, to make sure we don't overwrite unnecessarily.
Yeah, this is where it's getting long, 3 stuff to do for 3 different conditions. Maybe I'll really divide this thing into 3 functions.
----------------------------------------------------------------------------------------
I did come up with a cleaner version but it's slower than the ugly version.
This is the other "shorter" version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
char *
strrep(string, substr, repstr)
char *string, substr, repstr;
{
char *hstr = string;
int rlen = strlen(repstr);
int slen = strlen(substr);
char *htmp;
register char *tmp;
htmp = tmp = malloc((abs(rlen - slen)*strcnt(string,substr,NULL))+strlen(string));
if (!tmp)
return NULL;
while ((pos = strpos(string, substr)) != -1)
{
strncpy(tmp, string, pos);
tmp += pos;
strcpy(tmp, repstr);
tmp += rlen;
string += pos + slen;
}
strcpy(tmp, string);
strcpy(hstr, htmp);
free(htmp);
return hstr;
}
|
Okay, this is much much shorter and that does exactly the same job but is slower and allocates far too much memory.
Should I switch the fast but long function with this slow but simple function?