I am trying to improve my C skills, and I hope someone might be able to provide me with some feedback on the following code.
It is just basic string splitting, it should behave the similar to Ruby's String#split or Clojure's clojure.string.split. I couldn't think of a simple/efficient way to create an array of variable-size strings so I went the callback route.
Anyway, any and all feedback is greatly appreciated, thank you! Check out the code:
void strsplit(char *str, char *delim, int limit, void (*cb)(char *s, int idx))
{
char *search = strdup(str);
if (limit == 1) {
cb(search, 0);
}
else {
int i = 0, count = 0, len = strlen(str), len_delim = strlen(delim);
char *segment = NULL, *leftover = NULL;
limit = limit > 0 ? limit - 1 : len;
segment = strtok(search, delim);
for (i = 0; segment != NULL && i < limit; i++) {
count += strlen(segment) + len_delim;
cb(segment, i);
segment = strtok(NULL, delim);
}
if (len != limit && count < len) {
leftover = (char*) malloc(len - count + 1);
memcpy(leftover, str + count, len - count);
leftover[len - count] = '\0';
cb(leftover, i);
free(leftover);
}
}
}
Also see the code with a test framework.
strdupdoesn't lead to warm fuzzy feelings, andstrtokmakes me feel...less than happy. \$\endgroup\$strdupshould be avoided because it's non-standard (though, in fairness, it is pretty widely available).strtokshould be avoided because it's ugly to use, requires heroic efforts to be thread safe, and can't be used on string literals. Duplicating the input avoids the last problem, but not the other two. \$\endgroup\$freeon yoursearchstring since you calledstrdupto allocate it. \$\endgroup\$