#include #include #include /** * Note: The returned array must be malloced, assume caller calls free(). */ char** splitWordsBySeparator(char** words, int wordsSize, char separator, int* returnSize) { struct { char **data; unsigned long cap; unsigned long size; } ret = {0}; ret.cap = wordsSize; ret.data = calloc(ret.cap, sizeof(*ret.data)); for ( int i = 0; i < wordsSize; ++i ) { char *cstr = words[i]; unsigned long wsize = 0; unsigned long wcap = 32; while ( *cstr != '\0' ) { if ( *cstr == separator ) { if ( wsize > 0 ) { ret.data[ret.size][wsize++] = 0; ++ret.size; } wsize = 0; wcap = 32; if ( ret.size >= ret.cap ) { ret.cap *= 2; ret.data = realloc(ret.data, sizeof(*ret.data) * ret.cap); for ( unsigned long j = ret.size; j < ret.cap; ++j ) { ret.data[j] = NULL; } } ++cstr; continue; } if ( ret.data[ret.size] == NULL ) { ret.data[ret.size] = malloc(wcap); } ret.data[ret.size][wsize++] = *cstr; if ( wsize >= wcap ) { wcap *= 2; ret.data[ret.size] = realloc(ret.data[ret.size], wcap); } ++cstr; } if ( wsize != 0 ) { ret.data[ret.size++][wsize++] = 0; if ( ret.size >= ret.cap ) { ret.cap *= 2; ret.data = realloc(ret.data, sizeof(*ret.data) * ret.cap); for ( unsigned long j = ret.size; j < ret.cap; ++j ) { ret.data[j] = NULL; } } } } *returnSize = ret.size; return ret.data; } void r(char **ws, int s, char sep) { int ret_size = 0; char **ret = splitWordsBySeparator(ws, s, sep, &ret_size); printf("RetSize = %d\n", ret_size); if ( ret == NULL ) return; printf("Ret = ["); while ( *ret != NULL ) { printf("\"%s\", ", *ret++); } printf("]\n"); } int main(void) { char *words[] = {"one.two.three","four.five","six"}; r(words, 3, '.'); return 0; }