阿里面試題:實現Char ** StrToK(const char* S1,const char* S2)函數,阿里strtok
實現函數:Char ** StrToK(const char* S1,const char* S2)
功能:S2將S1字串截斷後,分別輸出截斷的字串。舉例例如S1=abcdefg, S2=be,將a,cd,fg三個字串用指向指標的指標返回。
#include <stdio.h>#include <string.h>#include <stdlib.h>char **str2tok(const char *s1,const char *s2){ int i=0,j=0; int hash[256]={}; char *q=s1,*p=s1; char **res = (char**)malloc(sizeof(char*)*strlen(s1)); while(*s2) { hash[*s2]=1; s2++; } while(*p) { if(hash[*p] != 1) { p++; i++; } else { if(i==0) { p++; q=p; } else { char *tmp=(char*)malloc(sizeof(char)*i+1); snprintf(tmp,i,"%s",q); tmp[i]='\0'; res[j]=tmp; j++; i=0; p++; q=p; } } } if(i>0) { char *tmp=(char*)malloc(sizeof(char)*i+1); snprintf(tmp,i,"%s",q); tmp[i]='\0'; res[j]=tmp; j++; } res[j]=NULL; return res;}int main(void){ char *s1="abcdef"; char *s2="be"; char **res=str2tok(s1,s2); while(*res) { printf("%s,",*res); res++; } printf("\n"); return 0;}
strtok函數
1、c99中函數定義是:
char * strtok(char * restrict s1, const char * restrict s2);
你所謂的那句話有可能是指不可用char *,因為這裡定義必須是const char *,而char[]因為數組的特性,其引用相當於const char *
比如你定義
char str[20];
char *p;
那麼
p++是有效,指標引用地址改變了。
str++或是無效的,變相等於了const char *
2、首次完成對字串分割後,分隔字元會被變成空格,此時如果將第一個參數置NULL即會按順序返回每個子字串,每調用一次返回一個,所以token會改變。當後面不再有子字串了,就會返回NULL
補充:
對,除非你給出的第一個參數不是NULL,這樣他會重新開始。
char *strtok_r(char *s, const char *delim, char **ptrptr);中char **ptrptr是幹嘛的
大部分*_r這種形式的函數基本都是可重新進入的函數,也可以認為是安全執行緒的函數,像這個函數strtok是用delim來切割s字串,每次返回最新的切割結果,對於這個函數來說,每次執行都必須知道上一次的執行結果,因此每次執行都需要儲存本次執行的狀態,對於沒有_r的函數,函數中使用static變數,但是在多線程時,很可能會出錯,因此這個ptrptr所指向的地址儲存的就是當前線程的調用結果,這樣不同線程調用這個函數的時候就不會出錯了, 具體是什麼內容使用者不必知道,只需要傳入一個有效地址就行了。