实现strtok_r()函数

来源:互联网 发布:安卓手机优化软件 编辑:程序博客网 时间:2024/05/18 13:43

   Linux中的字符串分段函数strtok()函数是不可重入和线程不安全的,所以后来又提供了相应的线程安全和可重入的函数strtok_r()函数,然而在window系统中对应的是strtok_r()函数,为了详细了解函数的代码结构,我按照相应的功能,自己编写了一个类似功能的字符串分割函数,代码如下,在vs2012中能够正常运行,如有错误还请指正!

//实现strtok函数class mystrtok{public:    char* operator()(char *src,const char *delim,char **save_ptr)    {        char *token=nullptr;        if(src==nullptr)            src=*save_ptr;        src+=_strspn(src,delim); //第一次src不为空,delim第一个不在s中的位置,_strspn(src,delim)返回0        if(*src=='\0')            return NULL;        token=src;        ///*******??????        src=_strpbrk(src,delim); //返回最早出现在src中的位置后的字符串,包括自身        if(src==NULL)        {            *save_ptr=_strchr(token,'\0');        }        else        {            *src='\0';            *save_ptr=src+1;        }        return token;    }private:    //检查delim第一个不在s中的位置    int _strspn(char *s,const char* delim)        {        if(s==nullptr||delim==nullptr)            return 0;        int n=0;        bool flag=false;        for(int i=0;i<strlen(s);i++)        {            //判断delim的中的字符是否在s中            for(int j=0;j<strlen(delim);j++)            {                if(delim[j]==s[i])                {                    n++;                    flag=true;                    break;                }                            }            if(!flag)                return n;            flag=false;        }        return n;  //返回的是n=0    }    //字符串s中首次出现dest的位置    char *_strchr(char *s,char dest)    {        if(s==nullptr||dest==NULL)            return nullptr;        int n=0;        for(int i=0;i<strlen(s);i++)        {            if(dest==s[i])                return s+n;            else                n++;        }        if(n==strlen(s))            return NULL;        else            return s;    }    //检查字符串delim在s中最早出现的位置后的字符串    char *_strpbrk(char* s,const char* delim)    {        if(s==nullptr||delim==nullptr)            return nullptr;        int min=0xffff;        //int n=0;        for(int i=0;i<strlen(delim);i++)        {            for(int j=0;j<strlen(s);j++)            {                if(delim[i]==s[j])                {                    min=j<min?j:min;                }            }        }        if(min==0xffff)  //没有找到相应的分割字符串            return NULL;        else            return s+min;    }};

  简单测试和c++库函数得到相同的结果,注意源码中strtok()函数的原型如下:

char *strtok(char *s, const char *delim)     {         static char *last;              return strtok_r(s, delim, &last);     }  
它是使用静态变量last保存save_ptr给保存起来,由于是静态变量,所以这次调用可能会影响下次调用,所以是不可重入和线程不安全的!


0 0