strtok函数源码

原创 2016年08月31日 09:04:43

今天用到strtok时,总感觉怪怪的,为啥第二次调用第一个参数要用NULL, 难道是函数内部保存了当前的状态,假如这样的话,那就不能对多个串交叉调用strtok了,而且保存这个状态的不是全局变量就是static变量。 于是看了他的源码,有几个不同的版本,思想是一样的。 感觉写的挺巧妙的,深深的折服这些写库函数的牛人了。 下面是源码

版本一

    char *s;            /* string to search for tokens */
    const char *delim;  /* delimiting characters */
{
    static char *lasts;
    register int ch;

    if (s == 0)
	s = lasts;
    do {
	if ((ch = *s++) == '\0')
	    return 0;
    } while (strchr(delim, ch));
    --s;
    lasts = s + strcspn(s, delim);
    if (*lasts != 0)
	*lasts++ = 0;
    return s;
}

上面用到了strcspn函数,这个函数返回值是n,表示s的前n个字符都没有在delim中出现。原理是这样的,函数在一开始判断第一个参数是不是空,假如是的话,也就是第二次调用这个函数了,那么把上一次的状态last赋值给要返回的串,然后那个do实现的功能其实就是strspn函数,这个函数的返回值是n,代表 s的前n个字符全部在delim出现。也就是说do实现的是跳过s中字符属于分隔符的字符。 然后通过下面的strcspn真正截取需要的字符数。所以last就指向了下一个分隔符或者字符末尾。然后判断last是否是末尾,假如不是的话,把当前的字符也就是分隔符标记成0,其实就是把前一段字符截断了。last指向了下一个字符。 然后返回s。


版本二 把do直接用 strspn函数代替,思想一样的


#include <string.h> /* strspn() strcspn() */
char *strtok(char * str, const char * delim)
{
    static char* p=0;
    if(str)
        p=str;
    else if(!p)
        return 0;
    str=p+strspn(p,delim);
    p=str+strcspn(str,delim);
    if(p==str)
        return p=0;
    p = *p ? *p=0,p+1 : 0;
    return str;
}


第三个版本直接是 没有使用任何函数,用的是哈希实现,这个哈希的妙处真是没谁了,这才是真正c语言程序好不好

char*  strtok_r(char* string_org,const char* demial) {
	static unsigned char* last; 
	unsigned char* str;         
	const unsigned char* ctrl = (const unsigned char*)demial;
	unsigned char map[32]; 
	int count;
	
	for (count =0; count <32; count++){
		map[count] = 0;
	}   
	do {
		map[*ctrl >> 3] |= (1 << (*ctrl & 7));
	} while (*ctrl++);     
	if (string_org){
		str = (unsigned char*)string_org;
	} else{
		str = last;
	}
	while ((map[*str >> 3] & (1 << (*str & 7)))  && *str){
		str++;
	} 
	string_org = (char*)str; 
	for (;*str; str++){
		if ( map[*str >> 3] & (1 << (*str & 7))){
			*str++ = '\0';
			break;         
		}         
	}    
	last =str;    
	if (string_org == (char*)str){
		return NULL; 
	}else{
		return string_org;
	}
}





版权声明:本文为博主原创文章,未经博主允许不得转载。

strtok源码剖析 位操作与空间压缩

地址:http://blog.csdn.net/morewindows/article/details/8740315转载请标明出处,谢谢。欢迎关注微博:http://weibo.com/MoreWi...
  • MoreWindows
  • MoreWindows
  • 2013年03月31日 11:51
  • 10090

strtok函数及其实现

头文件:#include 定义函数:char * strtok(char *s, const char *delim); 函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分...
  • Mormont
  • Mormont
  • 2016年12月15日 21:56
  • 2290

strtok、strtok_s、strtok_r 字符串分割函数

strtok strtok函数
  • hustfoxy
  • hustfoxy
  • 2014年04月11日 21:31
  • 57545

strcpy、strcat函数源码,strncpy,strncat,strncmp,strtok

已知strcpy函数的原型是: char * strcpy(char * strDest,const char * strSrc); 其中strDest是目的字符串,strSrc是源...
  • xdf191
  • xdf191
  • 2016年06月15日 21:33
  • 451

c语言字符串分割函数strtok

  • 2017年01月12日 10:38
  • 31KB
  • 下载

strtok函数C实现

  • 2012年03月21日 16:05
  • 1KB
  • 下载

C++ str系列函数 (包含strtok用法)

1、strcat() 此函数原型为 char *strcat(char *dest, const char *src). 功能为连接两个字符串,把src连接到dest后面;返回dest地址 实现...
  • modiziri
  • modiziri
  • 2014年12月05日 15:35
  • 1466

c,c++中字符串处理函数strtok,strstr,strchr,strsub

1,字符串切割函数 函数原型:char *strtok(char *s, char *delim); 函数功能:把字符串s按照字符串delim进行分割,然后返回分割的结果。 函...
  • wangqing_12345
  • wangqing_12345
  • 2016年06月25日 22:37
  • 3863

【一个按标志分拆字符串的好方法】strtok函数简介及应用。

刚刚接触strtok函数,感觉十分神奇。 定义: strtok 语法: #include char *strtok( char *str1, const ...
  • mig_davidli
  • mig_davidli
  • 2013年01月29日 10:46
  • 1108

C语言str系列库函数之strtok()

之所以系统地记下C语言的str系列函数,是因为4月份参加的两次shi
  • u013071074
  • u013071074
  • 2014年05月30日 23:06
  • 1071
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:strtok函数源码
举报原因:
原因补充:

(最多只允许输入30个字)