Created
April 2, 2017 14:37
-
-
Save cauefcr/47ee0b5dba3c61c91c1ef7980cf9d6da to your computer and use it in GitHub Desktop.
C string splitting (explode)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// return structure | |
struct str_explode_out { | |
size_t count; | |
char *strings[]; | |
}; | |
// destroys the input string and saves the pointer to the places that were not | |
// touched by the divider | |
struct str_explode_out *str_explode(char input[], const char divider[]) { | |
// could check here if the input and divider are not null or something | |
char *divtmp = strstr(input, divider); | |
size_t lendiv = strlen(divider); | |
size_t alloc = 8; | |
// allocate memory only "once" | |
struct str_explode_out *out = | |
malloc(sizeof(struct str_explode_out) + sizeof(char *) * alloc); | |
if (out == NULL) { | |
fprintf(stderr, "out of memory on line %i", __LINE__); | |
return NULL; | |
} | |
out->count = 0; | |
// count holds the number of times the string has been split | |
out->strings[0] = input; | |
// strings holds the pointer to the split places | |
out->count++; | |
// while there are still occurences of divider on the input string | |
while (divtmp != NULL) { | |
// set the places that had divider to 0, null terminating the string that was before it | |
memset(divtmp, '\0', lendiv); | |
// save the current location of the occurence of divider | |
out->strings[out->count++] = divtmp + lendiv; | |
// search for the next location of divider on what's left of the input | |
divtmp = strstr(divtmp + lendiv, divider); | |
// if the array is full and it's not the last element | |
if (out->count == alloc && divtmp != NULL) { | |
// save the pointer to the struct, so we don't leak memory in case of realloc failing | |
struct str_explode_out *tmp = out; | |
alloc *= 2; | |
//allocate more memory for the array | |
out = | |
realloc(out, sizeof(struct str_explode_out) + sizeof(char *) * alloc); | |
// if realloc failed | |
if (out == NULL) { | |
fprintf(stderr, "out of memory at line %d, returning half processed " | |
"data, good luck", | |
__LINE__); | |
return tmp; | |
} | |
} | |
} | |
return out; | |
} | |
int main() { | |
char test_base[] = "Example, string, number, uno"; | |
struct str_explode_out *output_split = str_explode(test_base, ", "); | |
for (int i = 0; i < output_split->count; i++) { | |
printf("%s\n", output_split->strings[i]); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment