今天在看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; }
輸出: