Skip to content

Instantly share code, notes, and snippets.

@m1nuz
Last active August 29, 2015 14:20
Show Gist options
  • Select an option

  • Save m1nuz/4bc077a11bcaf1455e82 to your computer and use it in GitHub Desktop.

Select an option

Save m1nuz/4bc077a11bcaf1455e82 to your computer and use it in GitHub Desktop.
str_replace in C
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#ifndef ABS
#define ABS(v) ((v) < 0 ? -(v) : (v))
#endif
char *
str_replace_once_fast(const char *orig, size_t orig_size,
const char *rep, size_t rep_size,
char *str, size_t str_size) {
assert(orig != NULL);
assert(rep != NULL);
assert(str != NULL);
const size_t sz = ABS((int)orig_size - (int)rep_size);
const size_t nbytes = str_size + sz + 1;
char *buffer = malloc(nbytes);
buffer[nbytes - 1] = 0;
char *p = memmem(str, str_size, orig, orig_size);
memcpy(buffer, str, p - str);
memcpy(buffer + (p - str), rep, rep_size);
const size_t n = str_size - (p - str) - orig_size;
memcpy(buffer + (p - str) + rep_size, p + orig_size, n);
return buffer;
}
char *
str_replace_fast(const char *orig, size_t orig_size,
const char *rep, size_t rep_size,
char *str, size_t str_size) {
assert(orig != NULL);
assert(rep != NULL);
assert(str != NULL);
size_t count;
char *t;
char *s = str;
for (count = 0; (t = memmem(s, str_size, orig, orig_size)) != NULL; count++)
s = t + rep_size;
const size_t sz = ABS((int)orig_size - (int)rep_size);
const size_t nbytes = str_size + sz * count + 1;
char *buffer = malloc(nbytes);
buffer[nbytes - 1] = 0;
char *q = str;
char *d = buffer;
while(count--) {
char *p = strstr(q, orig);
memcpy(d, q, p - q);
memcpy(d + (p - q), rep, rep_size);
const size_t n = str_size - (p - q) - orig_size + 1;
memcpy(d + (p - q) + rep_size, p + orig_size, n);
d += (p - q) + rep_size;
q = p + orig_size;
}
return buffer;
}
#pragma once
#if __STDC_VERSION__ < 199901L
#error "c99 not supported"
#endif
#include <string.h>
#define str_replace(orig, rep, str) \
str_replace_fast(orig, strlen(orig), rep, strlen(rep), str, strlen(str))
#define str_replace_once(orig, rep, str) \
str_replace_once_fast(orig, strlen(orig), rep, strlen(rep), str, strlen(str))
char *str_replace_once_fast(const char *orig, size_t orig_size,
const char *rep, size_t rep_size,
char *str, size_t str_size);
char *str_replace_fast(const char *orig, size_t orig_size,
const char *rep, size_t rep_size,
char *str, size_t str_size);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment