Search code examples
cconstantsc-stringsstrtokfunction-definition

strtok()function which does not modify the original string, and should create a new string for the tokens to be returned


I am trying to implement own strtok function but here i noticed that it changes the orginal string.I want to implement it in such a way it should create a new string for the tokens to be returned and it does not modify the original string. Although i implemented this in main function but it should be handled in strtok function in itself.

My code is given below:


char *my_strtok(char * s2, char * delimit);//function prototyping
int main()
{
   char arr1[50]={"abc-efgh-ijkl-mnopq"}; 
   char buffer[50];
   sprintf(buffer,"%s",arr1);//for retaining the original string
   char *split  = my_strtok(arr1,"-");
   
   while(split != NULL)
   {
       printf("%s\t",split);
       split=my_strtok(NULL,"-");
       
   }
   
   return 0;
}
char *my_strtok(char * s2, char * delimit)
{
   int j=0;
   static int curr;
   static char* s;
   int start=curr;
   if(s2 != NULL)
   {
       s=s2;
   }
   while(s[curr]!='\0')
   {
       j=0;
       while(delimit[j]!='\0')
       {
           if(s[curr]==delimit[j])//comparing the delimiter in the string
           {
               s[curr]='\0';//replaces the delimiter by delimiter
               curr=curr+1;//increment the curr position by 1
               if(s[start]!='\0')//here start=0 returns characters till encounters '\0'
               {
                  return (&s[start]);
                  
               }
               else
               {
                 start=curr;//Move to the next string after the delimiter
                 
               }
           }
        j++;   
       }
     curr++;  
   }
       
       
   s[curr] = '\0';
   if(s[start] == '\0')
       return NULL;
   else
       return &s[start];
}

Solution

  • I want to implement it in such a way it should create a new string for the tokens to be returned and it does not modify the original string.

    In this case the function parameters should be declared with the qualifier const like

    char * my_strtok( const char *s2, const char *delimit );
    

    After this if statement

    if(s2 != NULL)
    {
        s=s2;
    }
    

    the both pointers s and s2 point to the same string. So statements like this

    s[curr]='\0';
    

    change the original character array.

    You need to allocate dynamically an array for storing a sub-string. And in main you need to remember to free the dynamically allocated array when it is not required any more.

    The function can be defined for example the following way as it is shown in the demonstration program below.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char * my_strtok( const char *s, const char *delimit )
    {
        static const char *p;
    
        if ( ( s == NULL ) && (  p == NULL ||  *p == '\0' ) )
        {
            return NULL;
        }
    
        if ( s )
        {
            p = s;
        }
    
        p += strspn( p, delimit );
    
        if ( *p == '\0' )
        {
            return NULL;
        }
    
        const char *start = p;
    
        p += strcspn( p, delimit );
    
        size_t n = p - start;
    
        char *substr = malloc( n + 1 );
    
        if ( substr )
        {
            substr[n] = '\0';
            memcpy( substr, start, n );
        }
    
        return substr;                      
    }
    
    int main(void) 
    {
        const char *s = "abc-efgh-ijkl-mnopq";
    
        char *p = my_strtok( s, "-" );
    
        while ( p != NULL )
        {
            puts( p );
            free( p );
            p = my_strtok( NULL, "-" );
        }
    
        return 0;
    }
    

    The program output is

    abc
    efgh
    ijkl
    mnopq