You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于__strtok_r函数中strspn与strcspn代码逻辑的技术咨询

关于__strtok_r中两行代码的解析及自定义分隔符保留版strtok的思路

首先明确两个核心函数的行为,这是理解代码的关键:

  • strspn(s, delim):返回s开头连续属于delim集合的字符总数,简单说就是跳过开头所有分隔符的步数。
  • strcspn(s, delim):返回s开头连续不属于delim集合的字符总数,也就是找到第一个分隔符前的字符数。

1. s += strspn(s, delim); 的作用

这行代码的核心是跳过当前字符串开头所有的分隔符,把指针定位到下一个有效token的起始位置。

举你的例子:s = "Abc,dsf.eerr",delim = " ,.\n"
因为s开头的A、b、c都不属于分隔符集合,strspn(s, delim)返回0,所以s仍然指向A,而不是你以为的d。只有当s开头是分隔符时,比如s = ",dsf.eerr",strspn会返回1,s会跳到d的位置。


2. end = s + strcspn(s, delim); 的作用

这行是定位当前token的结束位置:strcspn会计算从s开始到第一个分隔符的字符数,s + 这个数值就指向第一个分隔符的地址(如果字符串末尾没有分隔符,则指向字符串结束的\0)。

还是你的例子:s指向A,strcspn(s, delim)返回3(A、b、c都不属于分隔符,下一个字符是,),所以end指向,的位置。原__strtok_r会在这里把*end设为\0,截断出当前token("Abc"),然后把下一次的起始位置设为end+1(指向d)。


3. 实现保留分隔符的strtok思路

如果你要保留分隔符并返回,需要调整原逻辑,把分隔符也作为结果的一部分返回(比如通过输出参数,或者返回包含token和分隔符的结构体),核心步骤可以是:

  • 先处理开头的分隔符(如果需要保留连续分隔符,比如多个逗号,也可以作为单独的分隔符返回)
  • 用strcspn找到第一个分隔符的位置:
    • 从当前s开始,token_len = strcspn(s, delim),所以token是s到s+token_len-1
    • 如果s[token_len]不是\0,则分隔符是s[token_len],下一次的起始位置设为s+token_len+1
    • 如果s[token_len]是\0,则没有分隔符,下一次返回NULL
  • 可以设计函数返回token的指针,同时通过指针参数返回分隔符(比如char *my_strtok(char *s, const char *delim, char *out_delim))

举个简化的逻辑示例:

char *my_strtok(char *s, const char *delim, char *out_delim) {
    static char *next = NULL;
    if (s != NULL) next = s;
    if (next == NULL || *next == '\0') return NULL;

    // 跳过开头分隔符(如果不需要保留开头分隔符,保留这行;如果要保留,注释掉并先处理分隔符)
    next += strspn(next, delim);
    if (*next == '\0') return NULL;

    char *token_start = next;
    size_t token_len = strcspn(next, delim);
    next += token_len;

    // 提取分隔符
    if (*next != '\0') {
        *out_delim = *next;
        next++; // 跳过分隔符,准备下一次调用
    } else {
        *out_delim = '\0';
    }

    // 不需要截断token,因为要保留原字符串?或者根据需求决定是否截断
    // 如果需要返回独立的token,可以分配内存复制,否则直接返回token_start
    return token_start;
}

内容的提问来源于stack exchange,提问作者DirtyV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:40:32