strsep() 函数将分割一个字符串。
char * strsep (char **stringp, const char *delim);
从 stringp 指向的位置起向后扫描,遇到 delim 指向的字符串中的字符后,将此字符替换为NULL,返回 stringp 指向的地址。
由于第二个参数 delim 也是字符串,因此猜想可能会采取类似 strcspn 的策略。查看 glibc 的实现,发现它是对于两种情况分别处理。
char *
strsep (char **stringp, const char *delim)
{
char *begin, *end;
begin = *stringp;
if (begin == NULL)
return NULL;
/* delim分隔符是单个字符的情况是非常频繁的,因此不需要使用代价昂贵的 strpbrk 函数
而只需要调用 strchr 就能解决 */
if (delim[0] == '\0' || delim[1] == '\0')
{
char ch = delim[0];
if (ch == '\0')
end = NULL;
else
{
if (*begin == ch)
end = begin;
else if (*begin == '\0')
end = NULL;
else
end = strchr (begin + 1, ch);
}
}
else
/* delim 有两个字符以上,才调用strpbrk */
end = strpbrk (begin, delim);
if (end)
{
/* 用0封闭这个token;返回stringp,指向一个null指针 */
*end++ = '\0';
*stringp = end;
}
else
/* 没有出现delim,这是最后一个token */
*stringp = NULL;
return begin;
}
这个函数的优化策略,是“二八定律”的一个应用。80%的情况下,分隔符都只有一个字节,可以用 strchr 函数优化它的性能至 O(n);而20%的情况分隔符才有多个字节,这个时候只需要提供完成函数的正常功能即可,该函数的整体性能是靠近 O(n) 的。