Coffee Space


Listen:

String Explode

Preview Image

It came to my attention that some people from PHP may be looking for an explode function for strings when using C/C++. I wrote a quick version that you could adopt to your use-case. Essentially it is just string splitting, but it may not be obvious to newcomers how to write this.

Other Methods

If you read up on Stackoverflow, it will suggest to use something like strtok(). Functions such as strtok() exist, but one of the negatives of this method is that it modifies the original string - something you may not want to do.

Implementation

Here we implement a version of the string splitting called str_explode(), with a matching function str_explode_free() - which must be called to deallocate memory. There is also the helper function str_copy().

0001 #include <stddef.h>
0002 #include <stdlib.h>
0003 #include <string.h>
0004 
0005 /**
0006  * str_copy()
0007  *
0008  * Copy a string from one pointer to another pointer into allocated memory,
0009  * with a NULL terminator added.
0010  *
0011  * @param str The start of the string to be copied.
0012  * @param end The end of the string to be copied.
0013  * @return A pointed to the copied string.
0014  **/
0015 char* str_copy(char* str, char* end){
0016   char* dest = (char*)malloc((end - str) + 1);
0017   memcpy(dest, str, end - str);
0018   dest[end - str] = '\0';
0019   return dest;
0020 }
0021 
0022 /**
0023  * str_explode()
0024  *
0025  * Split a C-string and return it.
0026  *
0027  * @param str The string to be split.
0028  * @param sep The separator string to be search for.
0029  * @return The allocated string array that needs to be freed.
0030  **/
0031 char** str_explode(char* str, char* sep){
0032   int size = 1;
0033   char** res = (char**)malloc(sizeof(char*) * size);
0034   char* end = str - 1;
0035   while(*str && *(++end)){
0036     char* s = sep;
0037     while(*s != '\0'){
0038       if(*s == *end){
0039         res = (char**)realloc(res, sizeof(char*) * ++size);
0040         res[size - 2] = str_copy(str, end);
0041         str = end + 1;
0042         break;
0043       }
0044       ++s;
0045     }
0046   }
0047   if(str != end + 1){
0048     res = (char**)realloc(res, sizeof(char*) * ++size);
0049     res[size - 2] = str_copy(str, end);
0050   }
0051   res[size - 1] = NULL;
0052   return res;
0053 }
0054 
0055 /**
0056  * str_explode_free()
0057  *
0058  * Free memory from an str_explode operation.
0059  *
0060  * @param s The array to be freed.
0061  **/
0062  void str_explode_free(char** s){
0063    char** z = s - 1;
0064    while(*(++z) != NULL) free(*z);
0065    free(s);
0066  }

To use it, you could do something like so:

0067 int main(){
0068   char* test = "This is a test string... Interesting right?";
0069   char* sep = " .";
0070   char** res = str_explode(test, sep);
0071   printf("%s\n", test);
0072   char** s = res;
0073   while(*s != NULL){
0074     printf("  %s\n", *s);
0075     ++s;
0076   }
0077   str_explode_free(res);
0078   return 0;
0079 }

This code will work in both C and C++ (maybe with some warnings).