今天在看strtok函数源码时,发现有点绕,就将源码的处理思想以图示的方式展示给你们,但愿能够帮助你们。函数
strtok函数spa
char *strtok( char *str1, const char *str2 );code
str1为须要分割的字符串,首次传入的是源字符串,后面就是NULLtoken
str2为分隔符字符串,此字符串中的每一个字符都是分割符ip
返回值:若是不存在分隔符,则返回NULL;存在则返回分割出的字符串的首地址,字符串首部不含分隔符,尾部是字符串结束符+余下的带分割的字符串。内存
注意:此函数是在源字符串中进行分割操做,如不想修改源字符串,最好copy一份。字符串
strtok函数源码:源码
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include <string.h> char* strtok(char *s, const char *delim) { const char *spanp; int c, sc; char *tok; static char *last; if (s == NULL && (s = last) == NULL) return (NULL); /* * Skip (span) leading delimiters (s += strspn(s, delim), sort of). * 跳过字符串首部的分隔符 */ cont: c = *s++; for (spanp = delim; (sc = *spanp++) != 0;) { if (c == sc) goto cont; } /* *分割符后面没有字符串了 */ if (c == 0) { /* no non-delimiter characters */ last = NULL; return (NULL); } tok = s - 1; /*分割符后面还有字符串,将tok指向字符串首部(不包括分隔符)*/ /* * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). * Note that delim must have one NUL; we stop if we see that, too. * 循环字符串中的字符,直到找到分隔符或者结束符,并替换成结束符 */ for (;;) { c = *s++; spanp = delim; /* *判断字符串中的某字符是不是分割符中的字符 *若是是,将分隔符替换成结束符并返回tok; *若是不是,继续判断下一个字符 */ do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; last = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ }
strtok函数思想图示:string
第一次:it
第二次:
第三次:
最后一次:
处理思想:
一、在原字符串中进行分隔,找到第一个匹配的分隔符,将此字符替换为结束符0
二、tok为首个不是分隔符的字符,last为找到的第一个匹配的分隔符字符下一位字符位置(也就是下次循环开始位置)
三、下一次循环开始忽略全部分隔符的字符。找到首个不是分隔符的字符赋值给tok
验证代码
#include <stdio.h> #include <string.h> /*打印内存空间函数*/ void printBuff(char buff[],int len) { int num,numCount; numCount=len; for(num=0; num < numCount; num++) { printf("%x ",buff[num]); } printf("\n"); } int main(int argc, char *argv[]) { char str[50] = "123aaaaaa23bbbbbbbbb2ccccccccc"; char delimt[3] = "123"; char* result = NULL; printBuff(str,50);/*打印str的内存空间*/ result = strtok(str,delimt); while(result != NULL) { printf("%s\n",result); result = strtok(NULL,delimt); } printBuff(str,50);/*打印str的内存空间*/ return 0; }
输出: