strtko_r和strsep函数源码分析

strtko_r和strsep函数都是Linux下面的字符串切割函数,但是使用时有许多地方需要注意,分析库里的函数实现源码可以帮助我们更好的使用该函数。

1.strtko_r函数源码

由于众多的版本。这里strtok_r函数源码来自于GNU C Library:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Parse S into tokens separated by characters in DELIM.
   If S is NULL, the saved pointer in SAVE_PTR is used as
   the next starting point.  For example:
        char s[] = "-abc-=-def";
        char *sp;
        x = strtok_r(s, "-", &sp);      // x = "abc", sp = "=-def"
        x = strtok_r(NULL, "-=", &sp);  // x = "def", sp = NULL
        x = strtok_r(NULL, "=", &sp);   // x = NULL
                // s = "abc\0-def\0"
*/
char* strtok_r(char *s, const char *delim, char **save_ptr) {
    char *token;
 
    if (s == NULL) s = *save_ptr;
 
    /* Scan leading delimiters.  */
    s += strspn(s, delim);//
        //这句话的作用是跳过开始第一个字符就是分隔符的情况;
    if (*s == '\0') 
		return NULL;
 
    /* Find the end of the token.  */
    token = s;
    s = strpbrk(token, delim);
    if (s == NULL)
        /* This token finishes the string.  */
        *save_ptr = strchr(token, '\0');//函数strchr 在参数 token 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置
        //返回一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针
    else {
        /* Terminate the token and make *SAVE_PTR point past it.  */
        *s = '\0';
        *save_ptr = s + 1;
    }
 
    return token;
}

int main()
{
    char tmp[] ="-abc-=-def";  
    char* ptr;
    char *rc = strtok_r(tmp,"-",&ptr);
    printf("%s\n",rc);
    rc = strtok_r(NULL,"=-",&ptr);
    printf("%s\n",rc);
    return 0;
    
}

这里主要注意源码里strspn 和 strbrp函数,理解了这两个函数的作用就理解了strtko_r源码。

s += strspn(s, delim);

函数strspn返回 s 中第一个不在字符串 deklim 中出现的字符下标。若strspn()返回的数值为n,则代表字符串s 开头连续有n 个字符都是属于字符串delim内的字符,这句话的作用是跳过开始第一个字符就是分隔符的情况

s = strpbrk(token, delim);

函数strpbrk依次检验字符串 token 中的字符(不包含空结束字符),即将token中的每个字符和delim中的每个字符比对,当被检验字符(delim中的字符)在字符串 token 中也包含时,则停止检验,并返回该字符位置,如果未找到字符则返回 NULL。
这句话的作用是在被分割字符串中查找分隔符,如果找到将指针指向该处; 后面将该处的分隔符替换成字符串结束符。

2. strsep函数源码

函数原型 char *strsep(char **stringp, const char *delim);

/*
 * Get next token from string *stringp, where tokens are possibly-empty
 * strings separated by characters from delim.
 *
 * Writes NULs into the string at *stringp to end tokens.
 * delim need not remain constant from call to call.
 * On return, *stringp points past the last NUL written (if there might
 * be further tokens), or is NULL (if there are definitely no moretokens).
 *
 * If *stringp is NULL, strsep returns NULL.
 */
char *strsep(char **stringp, const char *delim)
{
    char *s;
    const char *spanp;
    int c, sc;
    char *tok;
    if ((s = *stringp)== NULL)
        return (NULL);
    for (tok = s;;) {
        c = *s++;
        spanp = delim;
        do {
            if ((sc =*spanp++) == c) {
                if (c == 0)
                    s = NULL;
                else
                    s[-1] = 0;
                *stringp = s;
                return (tok);
            }
        } while (sc != 0);
    }
    /* NOTREACHED */
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值