////////////////////////////////////////////////////////////////////////////////////////////////////////////

split.c

#include "split.h"

 

char **split(char *str, char *sep, int max_strs, int *toks, char meta)

{

   char **retstr;    /* 2D array which is returned to caller */

   char *idx;         /* index pointer into str */

   char *end;        /* ptr to end of str */

   char *sep_end; /* ptr to end of seperator string */

   char *sep_idx;  /* index ptr into seperator string */

   int len = 0;        /* length of current token string */

   int curr_str = 0;  /* current index into the 2D return array */

   char last_char = (char)0xFF;

#ifdef DEBUG

   printf("[*] Splitting string: %s\n", str);

   printf("curr_str = %d\n", curr_str);

#endif

   /* find the ends of the respective passed strings so our while() 

      loops know where to stop */

   sep_end = sep + strlen(sep);

   end = str + strlen(str);

   /* remove trailing whitespace */

   while(isspace((int)*(end-1)) && ((end-1) >= str)) *(--end) = '\0'; /* -1 because of NULL */

   /* set our indexing pointers */

   sep_idx = sep;

   idx = str;

   /* alloc space for the return string, this is where the pointers to the tokens will be stored */

   retstr = (char **) malloc((sizeof(char **) * max_strs));

   max_strs--;

#ifdef DEBUG

   printf("max_strs = %d  curr_str = %d\n", max_strs, curr_str);

#endif

   /* loop thru each letter in the string being tokenized */

   while (idx < end)

   {

       /* loop thru each seperator string char */

       while (sep_idx < sep_end)

       {

           /* if the current string-indexed char matches the current seperator char... */

           if ((*idx == *sep_idx) && (last_char != meta))

           {

               /* if there's something to store... */

               if (len > 0)

               {

#ifdef DEBUG

                   printf("Allocating %d bytes for token ", len + 1);

                   fflush(stdout);

#endif

                   if(curr_str <= max_strs)

                   {

                       /* allocate space for the new token */

                       retstr[curr_str] = (char *) malloc((sizeof(char) * len) + 1);

                       /* make sure we got a good allocation */

                       if (retstr[curr_str] == NULL)

                       {

                           //fprintf(stderr, "msplit() got NULL substring malloc!\n");

                           //exit(1);

  return 0;

                       }

                       /* copy the token into the return string array */

                       memcpy(retstr[curr_str], (idx - len), len);

                       retstr[curr_str][len] = 0; 

#ifdef DEBUG

                       printf("tok[%d]: %s\n", curr_str, retstr[curr_str]);

                       fflush(stdout);

#endif

                       /* twiddle the necessary pointers and vars */

                       len = 0;

                       curr_str++;

#ifdef DEBUG

                       printf("curr_str = %d\n", curr_str);

                       printf("max_strs = %d  curr_str = %d\n", max_strs, curr_str);

#endif

                       last_char = *idx;

                       idx++;

                   }

#ifdef DEBUG

                   printf("Checking if curr_str (%d) >= max_strs (%d)\n", curr_str, max_strs);

#endif

                   /* if we've gotten all the tokens requested, return the list */

                   if (curr_str >= max_strs)

                   {

                      while(isspace((int)*idx)) idx++;

                      len = end - idx;

#ifdef DEBUG

                      printf("Finishing up...\n");

                      printf("Allocating %d bytes for last token ", len + 1);

                      fflush(stdout);

#endif

                      retstr[curr_str] = (char *) malloc((sizeof(char) * len) + 1);

                      if (retstr[curr_str] == NULL)

                         printf("Got NULL back from substr malloc\n");

                      memcpy(retstr[curr_str], idx, len);

                      retstr[curr_str][len] = 0;

#ifdef DEBUG

                      printf("tok[%d]: %s\n", curr_str, retstr[curr_str]);

                      fflush(stdout);

#endif

                       *toks = curr_str + 1;

#ifdef DEBUG

                       printf("max_strs = %d  curr_str = %d\n", max_strs, curr_str);

                       printf("mSplit got %d tokens!\n", *toks);

                       fflush(stdout);

#endif

                       return retstr;

                   }

               }

               else  /* otherwise, the previous char was a seperator as well, and we should just continue */

               {

                   last_char = *idx;

                   idx++;

                   /* make sure to reset this so we test all the sep. chars */

                   sep_idx = sep;

                   len = 0;

               }

           }

           else

           {

               /* go to the next seperator */

               sep_idx++;

           }

       }

       sep_idx = sep;

       len++;

       last_char = *idx;

       idx++;

   }

   /* put the last string into the list */

   if (len > 0)

   {

#ifdef DEBUG

       printf("Allocating %d bytes for last token ", len + 1);

       fflush(stdout);

#endif

       retstr[curr_str] = (char *) malloc((sizeof(char) * len) + 1);

       if (retstr[curr_str] == NULL)

           printf("Got NULL back from substr malloc\n");

       memcpy(retstr[curr_str], (idx - len), len);

       retstr[curr_str][len] = 0;

#ifdef DEBUG

       printf("tok[%d]: %s\n", curr_str, retstr[curr_str]);

       fflush(stdout);

#endif

       *toks = curr_str + 1;

   }

#ifdef DEBUG

   printf("mSplit got %d tokens!\n", *toks);

   fflush(stdout);

#endif

 

   /* return the token list */

   return retstr;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////
split.h
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"

#define MAX_STR 15

char **split(char *str, char *sep, int max_str, int *toks, char meta);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
using

char **toks;     // split에서 리턴값이 이중포인터라 이걸 받는 변수.
char *ptr = "Under the Hood for Viva!";
int num;            // split함수에서 리턴되는 toks의 갯수.
toks = split(ptr, " ", 10, &num, 0);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ Recent posts