首页 > 解决方案 > strtok() 函数,它不会修改原始字符串,并且应该为要返回的令牌创建一个新字符串

问题描述

我正在尝试实现自己的 strtok 函数,但在这里我注意到它改变了原始字符串。我想以这样的方式实现它,它应该为要返回的令牌创建一个新字符串,并且它不会修改原始字符串。虽然我在 main 函数中实现了这个,但它应该在 strtok 函数本身中处理。

我的代码如下:


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];
}

标签: cconstantsc-stringsstrtokfunction-definition

解决方案


我想以这样的方式实现它,它应该为要返回的令牌创建一个新字符串,并且它不会修改原始字符串。

在这种情况下,函数参数应使用限定符声明,const

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

在这个 if 语句之后

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

两个指针都指向ss2一个字符串。所以像这样的陈述

s[curr]='\0';

改变原来的字符数组。

您需要动态分配一个数组来存储子字符串。并且在 main 中,您需要记住在不再需要动态分配的数组时释放它。

例如,该功能可以通过以下方式定义,如下面的演示程序所示。

#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;
}

程序输出为

abc
efgh
ijkl
mnopq

推荐阅读