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和strtok_r源码解析

strtok源码简析 //官方的strtok函数,用来通过分隔字符(不支持字符串,传入的串中每个字符单独当分隔符,如下例子组合的如123会处理1而23会被跳过),返回分隔的串的首地址 //...

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

地址:http://blog.csdn.net/morewindows/article/details/8740315转载请标明出处,谢谢。欢迎关注微博:http://weibo.com/MoreWi...

C语言之strtok函数

【FROM MSDN && 百科】 原型: char *strtok(char *s, const char *delim); #include 分解字符串为一组字符串。s为要分解的...

关于函数strtok和strtok_r的使用要点和实现原理(一)

strtok函数的使用是一个老生常谈的问题了。该函数的作用很大,争议也很大。以下的表述可能与一些资料有区别或者说与你原来的认识有差异,因此,我尽量以实验为证。交代一下实验环境是必要的,winxp+vc...

strtok函数的实现

原型:extern char *strtok(char *s, char *delim);   用法:#include    功能:分解字符串为一组标记串。s为要分解的字符串,delim为分隔符字符串...
  • yskcg
  • yskcg
  • 2010-12-07 13:40
  • 877

strtok函数及其实现

头文件:#include 定义函数:char * strtok(char *s, const char *delim); 函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分...

借助strtok实现split笔记

代码://借助strtok实现split #include #include #include using namespace std; /**strtok 函数 定义 char *strtok(...

C\C++中strcat()函数

将两个char类型链接。 char d[20]="GoldenGlobal"; char *s="View"; strcat(d,s); 结果放在d中 printf("%s",d);...

memcpy函数实现

1.原型:void *memcpy(void *dest, const void *src,size_t size);     头文件:#include ;     功能:由src所指内存区域复制...

strstr函数的自己实现

请用标准C语言实现下列标准库函数,设计中不得使用其他库函数。 char *strstr(char *str1,char *str2); 在字符串str1中,寻找字串str2,若找到返回找到的位置,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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