去年的一个笔记,翻出来看看,两个程序原理是一样的,只是MS的strtok用了hash tabledelimeter(也就是匹配符)可以有很多个,满足其中一个就可以,不需要全部匹配也就是说:ct= 'abc',那么直要含有a或者b或者c的字符串都会被分割,而不是abc连着分割(刚开始都记错了,囧)PS:VC的调试技巧还是学的不够透彻啊~~~~~~~,又学了一个新技巧
char *strtok (char *s,char *ct)
{
char *t;
if (!s)
s = ts; /* use previous token if none specified */
if (!(s && *s))
return NULL; /* no tokens */
/* find any leading delimiters */
/* 注意是leading,就是刚开始的delimeter
这一段do-while代码的作用是如果字符串开始就有相应的delimeter,就把他们去除,如果不加这段代码也行,
但是光下面这两个for循环,很难简单判断输出字符的后面是否还是delimeter,会输出一些空值*/
do
for (t = ct, ts = NULL; *t; t++) //t等于分隔符号,ts初始值为null,检测分隔符是否为空,弱不为空,则t++
//ts在非第一次的时候保存着上一次的字符串,要重新赋给空置,所以循环里面一定要
{
if (*t == *s)
{//如果分隔符号和那个字符串相等
if (*(ts = ++s))
break; /* yes, restart seach if more in string */
return ts = NULL; /* else no more tokens */
}
}
while (ts); /* continue until no more leading delimiters */
/* can we find a new 注意,是new delimiter? */
for (ts = s; *ts; ts++)
for (t = ct; *t; t++)
{
if (*t == *ts)
{
*ts++ = '\0'; /* yes, tie off token at that point */
return s; /* return our token */
}
}
ts = NULL; /* no more tokens */
return s; /* return final token */
}
char* strtok_r(char* string_org,const char* demial)
{
static unsigned char* last; //保存分隔后剩余的部分
unsigned char* str; //返回的字符串
const unsigned char* ctrl = (const unsigned char*)demial;//分隔字符
//hash表
unsigned char map[32];
int count;
for (count =0; count <32; count++)
{
map[count] = 0;
}
//把匹配字符放入表中
//放入的算法是把匹配字符右移3位,相当于除以8,的数值 并上(加上)
//匹配字符与7,得到低3位,得出的结果,是把1左移的位数。最大左移位数是7,
do
{
map[*ctrl >> 3] |= (1 << (*ctrl & 7));
/*'a' 是97,'b'==98 都是映射到了map[12]
会映射到map1[12]的共有8个字符,要如何区分这8个字符,则是除以8的余数
'a'除以8的余数是1,'b'除以8的余数是2,
如果map[12] = 0000 0110,则表示'a','b'映射进来了*/
} 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';//当找到时,把匹配字符填为0,并且把str指向下一位。
break; //退出循环
}
}
last =str; // 把剩余字符串的指针保存到静态变量last中。
if (string_org == (char*)str)
{
return NULL; //没有找到,也就是没有移动指针的位置,返回NULL
}
else
{
return string_org; //找到了,返回之前字符串的头指针
}
}