I've since updated this function to not use sprintf. It's still deliberately limited to 512 (512 + 1 = 513) characters as that's the maximum length of an IRC message, but simply replacing that number will allow you to use longer strings if you need them.
Some notes again: Those who have suggested that I could have used strlen are correct, though I'd prefer not to make assumptions about the second buffer. If you'd like to, it's a trivial fix (Replace 513 with the result of strlen in a size_t)
Again, if you'd like to use this in the same way as PHP's str_replace, with three arguments, you're going to need a wrapper function. I forgot to include it last time, or I may have intentionally left it since it's another simple thing to do, but I'll include it this time anyway.
If anyone can further improve this, either reply to the topic or drop me an e-mail via (username)@arloria.net, either works. Genuine improvements sent via e-mail will be posted with attribution.
So, improved str_replace:
char *str_replace_(const char *search, const char *replace, const char *subject, char *buffer) {
char *p;
char *next;
size_t length;
if(!search || *search == '\0') {
return (char *)subject;
}
p = strstr(subject, search);
if(!p) {
return (char *)subject;
}
length = strlen(search);
memset(buffer, 0, 513);
strncat(buffer, subject, p - subject);
while(p != 0) {
next = strstr(p + length, search);
strncat(buffer, replace, 513);
if(next) {
strncat(buffer, p + length, next - p - length);
}
else
{
strncat(buffer, p + length, 513);
}
p = next;
}
return buffer;
}
Wrapper:
char *str_replace(char *search, char *replace, char *subject) {
char *buffer;
buffer = malloc(513);
if(buffer) {
return str_replace_(search, replace, subject, buffer);
}
return 0;
}
Some notes again: Those who have suggested that I could have used strlen are correct, though I'd prefer not to make assumptions about the second buffer. If you'd like to, it's a trivial fix (Replace 513 with the result of strlen in a size_t)
Again, if you'd like to use this in the same way as PHP's str_replace, with three arguments, you're going to need a wrapper function. I forgot to include it last time, or I may have intentionally left it since it's another simple thing to do, but I'll include it this time anyway.
If anyone can further improve this, either reply to the topic or drop me an e-mail via (username)@arloria.net, either works. Genuine improvements sent via e-mail will be posted with attribution.
So, improved str_replace:
char *str_replace_(const char *search, const char *replace, const char *subject, char *buffer) {
char *p;
char *next;
size_t length;
if(!search || *search == '\0') {
return (char *)subject;
}
p = strstr(subject, search);
if(!p) {
return (char *)subject;
}
length = strlen(search);
memset(buffer, 0, 513);
strncat(buffer, subject, p - subject);
while(p != 0) {
next = strstr(p + length, search);
strncat(buffer, replace, 513);
if(next) {
strncat(buffer, p + length, next - p - length);
}
else
{
strncat(buffer, p + length, 513);
}
p = next;
}
return buffer;
}
Wrapper:
char *str_replace(char *search, char *replace, char *subject) {
char *buffer;
buffer = malloc(513);
if(buffer) {
return str_replace_(search, replace, subject, buffer);
}
return 0;
}
Lulolwen is a tardbukkit







A few more notes about this function than should be necessary given its length:
It doesn't allocate memory, you need to allocate the required number of bytes into buffer before passing it into this function, therefore I've named it str_replace_ - You could write a wrapper str_replace that allocates memory and then calls str_replace_, in order to match PHP's argument count.
There's no "array" functionality to it, mainly due to fundamental differences in PHP and C, if you need that, simply call it in a loop.
The function is limited to 512 bytes. If you need more, just increase it. I presume that if you need to use this function, you'll know how to increase a hard-coded number.
If anyone finds this useful or has corrections or improvements, please do post and let me know. This version works as far as I can test it (Which has been pretty far, I've used this in things I'm working on), and I can't see any issues with it.
char *str_replace_(char *search, char *replace, char *subject, char *buffer) {
char *p;
int i, diff;
if(!search || *search == 0) {
return subject;
}
p = strstr(subject, search);
if(!p) {
return subject;
}
strncpy(buffer, subject, 512);
diff = strlen(search) - strlen(replace);
for(i = 0; p != 0; i++) {
sprintf(buffer + (p - subject - (i * diff)), "%s%s", replace, p + strlen(search));
p = strstr(p + strlen(search), search);
}
return buffer;
}