Advertisement
Guest User

split implementation in C, that does not use malloc/calloc

a guest
Oct 2nd, 2018
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.49 KB | None | 0 0
  1. //unit test: https://www.onlinegdb.com/online_c_compiler
  2. //copy paste example, press Run
  3.  
  4. #include <stdio.h>
  5. #include <stdbool.h>
  6. #include <string.h>
  7.  
  8.  
  9. //taken from https://stackoverflow.com/questions/9052490/find-the-count-of-substring-in-string
  10. //modified by Coto
  11.  
  12. static int count_substr(const char *str, const char* substr, bool overlap) {
  13.   if (strlen(substr) == 0) return -1; // forbid empty substr
  14.  
  15.   int count = 0;
  16.   int increment = overlap ? 1 : strlen(substr);
  17.   for (char* s = (char*)str; (s = strstr(s, substr)); s += increment)
  18.     ++count;
  19.   return count;
  20. }
  21.  
  22. static char outPath[256];    //used by split function as output path buffer
  23. typedef void(*split_fn)(const char *, size_t, char * ,int indexToLeftOut, char * delim);
  24. void split(const char *str, char sep, split_fn fun, char * outBuf, int indexToLeftOut)
  25. {
  26.     unsigned int start = 0, stop = 0;
  27.     for (stop = 0; str[stop]; stop++) {
  28.         if (str[stop] == sep) {
  29.             fun(str + start, stop - start, outBuf, indexToLeftOut, &sep);
  30.             start = stop + 1;
  31.         }
  32.     }
  33.     fun(str + start, stop - start, outBuf, indexToLeftOut, &sep);
  34. }
  35.  
  36. static int index = 0;
  37.  
  38. //this callback debugs every character separated from split()
  39. void print(const char *str, size_t len, char * outBuf, int indexToLeftOut, char * delim){
  40.     if(index != indexToLeftOut){
  41.         char localBuf[256];
  42.         snprintf(localBuf,len+1,"%s",str);
  43.         printf(" %d:%s%s:%d\n", (int)len, localBuf, delim,index);
  44.         index++;
  45.     }
  46. }
  47.  
  48. //this callback builds an output path (outBuf) and filters out the desired index. (used as a trim last directory callback)
  49. void buildPath(const char *str, size_t len, char * outBuf, int indexToLeftOut, char * delim){
  50.     if(index != indexToLeftOut){
  51.         if(strlen(outBuf) == 0){
  52.             snprintf(outBuf,len+2,"%s%s",str, delim);
  53.         }
  54.         else{
  55.             char localBuf[256];
  56.             sprintf(localBuf,"%s",outBuf);
  57.             snprintf(outBuf,strlen(outBuf)+len+2,"%s%s%s",localBuf,str,delim);
  58.         }
  59.         index++;
  60.     }
  61. }
  62.  
  63. //this callback splits the haystack found in a stream, in the outBuf
  64. #define TOP_ITEMS_SPLIT (int)(10)
  65. char * outSplitBuf[TOP_ITEMS_SPLIT][256];
  66. void splitCallback(const char *str, size_t len, char * outBuf, int indexToLeftOut, char * delim){
  67.     snprintf((char*)&outSplitBuf[index][0],len+1,"%s",str);
  68.     index++;
  69. }
  70.  
  71. int getLastDirFromPath(char * stream, char * haystack, char * outBuf){
  72.     index = 0;
  73.     int indexToLeftOut = count_substr(stream, haystack, false);
  74.     int indexToLeftOutCopy = indexToLeftOut;
  75.     if(indexToLeftOutCopy > 1){ //allow index 0 to exist, so it's always left the minimum directory
  76.         indexToLeftOutCopy--;
  77.     }
  78.     split(stream, (char)*haystack, buildPath, outBuf, indexToLeftOutCopy);
  79.     return indexToLeftOut;
  80. }
  81.  
  82. int str_split(char * stream, char * haystack, char * outBuf){
  83.     index = 0;
  84.     int indexToLeftOut = count_substr(stream, haystack, false);
  85.     split(stream, (char)*haystack, splitCallback, outBuf, indexToLeftOut);
  86.     return indexToLeftOut;
  87. }
  88.  
  89.  
  90.  
  91. int main(){
  92.     char str[] = "0:/folder0/folder1/";
  93.     char * delimiter = "/";
  94.     printf("getLastDirFromPath():Occurrences:%d->%s \n",getLastDirFromPath(str, delimiter, outPath),outPath);
  95.     int item = 1;   //item to show in the split buffer that was found by str_split() call
  96.     char * splitBuf = (char*)&outSplitBuf[item][0];
  97.     str_split(str, delimiter, NULL);
  98.     printf("str_split():%s",splitBuf);
  99.     return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement