字串分割函式是非常重要的乙個函式,就連如何使用也需要大家花上一段時間。所以這裡首先說一下strtok的處理方式:
strtok會首先過濾掉所有的所有的屬於分割字串集合的字元,然後進行掃瞄並將之後碰到的屬於分割字串集合中的字元使用空結束符'/0'來替代,這樣就可以直接使用該函式返回的直接讀取第乙個token(因為它讀到'/0'就結束了,很好!!!!)。之後獲取剩下的token的時候直接給strtok傳遞null作為第乙個引數,從而不斷取得下乙個token。
如果大家使用的比較多,或者通過我上面的描述一定會很疑惑,**是怎麼實現的?為什麼傳遞乙個null就可以獲取下乙個token了?返回的指標值一定又移到了下乙個地方(上乙個token後的乙個位置),如果每次都從頭開始掃瞄,怎麼知道在何處停下?因為程式根本不知道當前要處理的是第幾個token啊,我只是簡單的傳遞了乙個null值而已。
原來,這裡使用了乙個靜態變數,通過對該靜態變數的操作來保證對指標的修改(基於上乙個token的記錄);除此之外,strtok另乙個不太好的地方是它修改了原字串,將對應位置替換為了'/0',這也是為什麼這個函式的第乙個引數不能是const char * 的原因。
下面是strtok實現的**:
view plain
copy to clipboard
print?
static
char* ts=null;
char* strtok(char* s,const
char* ct)
} }while(ts);
for(ts=s;*ts;ts++)
for(t=ct;*t;t++)
if(*ts==*t)
ts=null;
return s;
}
請注意仔細學習上面的**。下面一部分內容很重要:
因為strtok函式使用了全域性的靜態變數,因此該函式是不可重入的,而且也不是執行緒安全的,因此在同一時間內多次使用該函式和多個執行緒使用該函式時會出現問題。
由此產生了該函式的可重入版本:strrtok,多出的乙個r意即reentrant(可重入),這兩個函式的優缺點以及例項效果分析請參考: ,裡面有詳細的比較。
而strrtok又是如何實現其可重入的呢,它只是多出了乙個引數而已,strrtok的函式原型為:
char *strtok_r(char *s, const char *delim, char **ptrptr);
原來,後來的ptrptr是用來傳遞乙個指標的引用,因此在使用該函式前需要先在外面定義乙個指標變數,這個變數剛好可以替代了strtok中的靜態變數的作用,因此不同的使用過程定義不同的乙個指標變數傳遞進去即可,從而很好的實現了可重入性:維護自己的變數。
下面是strrtok的乙份原始碼,供參考:
view plain
copy to clipboard
print?
char * strtok_r(char *s1, const
char *s2, char **lasts)
有關函式的可重入及執行緒安全的概念請參考:
分割字串 strtok 函式
在這個競爭的社會,對手無處不在,相信好勝心或者自尊心每個人都有,別人想要時時刻刻處處都要超越你,面對競爭對手或許它會採取各種手段來對付你,不要不相信,這種無恥的人是有的,那麼對待它們首先要做到的一點就是忍,暴力是衝動的不明智的選擇,它只會使你滿足一瞬間的慾望,卻會給自己帶來無窮的傷害,甚至會毀掉自己...
字串分割函式strtok
分解字串為一組字串。s為要分解的字串,delim為分隔符字串。例如 strtok abc,def,ghi 最後可以分割成為abc def ghi.尤其在點分十進位制的ip中提取應用較多。strtok 用來將字串分割成乙個個片段。引數s指向欲分割的字串,引數delim則為分割字串中包含的所有字元。當s...
分割字串函式strtok
char strtok char s,const char delim 作用 分解字串為一組字串。s為要分解的字串,delim為分隔符字串。說明 strtok 用來將字串分割成乙個個片段。引數s指向欲分割的字串,引數delim則為分割字串,當strtok 在引數s的字串中發現到引數delim的分割字...