这个可恶的strtok,几乎差点让初涉编坛的我痛哭流涕,看看这下面的实现源码之一
/* Find token in string
* Accepts: source pointer or NIL to use previous source
* vector of token delimiters pointer
* Returns: pointer to next token
*/
static char *ts = NIL; /* string to locate tokens */
char *strtok (char *s,char *ct)
{
char *t;
if (!s) s = ts; /* use previous token if none specified */
if (!(s && *s)) return NIL; /* no tokens */
/* find any leading delimiters */
do for (t = ct, ts = NIL; *t; t++) if (*t == *s) {
if (*(ts = ++s)) break; /* yes, restart seach if more in string */
return ts = NIL; /* else no more tokens */
} while (ts); /* continue until no more leading delimiters */
/* can we find a 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 = NIL; /* no more tokens */
return s; /* return final token */
}
多么美妙的代码,然而对于不熟悉它的人来说,噩梦随时会降临。
就像我,在我伟大的模块大功告成进入系统测试后,突然发现我的输入不定时的要被搞的乱其八遭,几次输入的数据之间总是藕断丝连,你中有我,我中有你。在哀哀地排错排了一周后,strtok才算是被我怀疑上,别怪我用时太多,那时候我在编程界还是乳臭未干的臭屁青年(虽然现在也是。。。)。网上一查,果真如此,这个优雅的strtok用它优雅的缺陷告诉我,不熟悉的东西就不要乱用,用啥东西都要事先把他18个朝代的历史背的滚瓜乱熟(此处省略N字)。。。我万万没有想到这样一个库函数居然轻率地使用了静态变量,在并发编程几乎泛滥的今天,这是多么伟大的一个缺陷。
所以,同志们,要警惕啊,如果你在多个线程中使用strtok,请务必对它进行改造,我宁愿多传一个参数,如strtok_r.