標籤:asm 運行時 rac replace img 指標 from code library
函數原型:
char *strtok(char *s, const char *delim);
char *strsep(char **s, const char *delim);
功能:strtok和strsep兩個函數的功能都是用來分解字串為一組字串。s為要分解的字串,delim為分隔字元字串。
傳回值:從s開頭開始的一個個子串,當沒有分割的子串時返回NULL。
相同點:兩者都會改變源字串,想要避免,可以使用strdupa(由allocate函數實現)或strdup(由malloc函數實現)。
strtok函數第一次調用時會把s字串中所有在delim中出現的字元替換為NULL。然後通過依次調用strtok(NULL, delim)得到各部分子串。
作用:
分解字串為一組字串。s為要分解的字串,delim為分隔字元字串。
說明:
strtok()用來將字串分割成一個個片段。參數s指向欲分割的字串,參數delim則為分割字串,當strtok()在參數s的字串中發現到參數delim的分割字元時則會將該字元改為\0 字元。在第一次調用時,strtok()必需給予參數s字串,往後的調用則將參數s設定成NULL。每次調用成功則返回下一個分割後的字串指標。
傳回值:
從s開頭開始的一個個被分割的串。當沒有被分割的串時則返回NULL。
所有delim中包含的字元都會被濾掉,並將被濾掉的地方設為一處分割的節點。(如下面的例子,可修改 seps裡面的資料,然後看輸出結果)
#include <string.h>#include <stdio.h>char string[] ="A string\tof ,,tokens\nand some more tokens";char seps[] =" ,\t\n";char *token;int main( void ){ printf( "%s\n\nTokens:\n", string );/* Establish string and get the first token: */ token = strtok( string, seps );while( token != NULL ) {/* While there are tokens in "string" */ printf( " %s\n", token );/* Get next token: */ token = strtok( NULL, seps ); }return 0;}
總結:
strtok內部記錄上次調用字串的位置,所以不支援多線程,可重入版本為strtok_r,有興趣的可以研究一下。它適用於分割關鍵字在字串之間是“單獨”或是 “連續“在一起的情況。
strsep:
#include <string.h>#include <stdio.h>char string[] ="A string\tof ,,tokens\nand some more tokens";char seps[] =" ,\t\n";char *token, *s;int main( void ){ printf( "%s\n\nTokens:\n", string );/* Establish string and get the first token: */ s=string; token = strsep( &s, seps );while( token != NULL ) {/* While there are tokens in "string" */ printf( " %s\n", token );/* Get next token: */ token = strsep( &s, seps ); }return 0;}
為什麼用strtok時子串中間沒有出現換行,而strsep卻有多個換行呢?文檔中有如下的解釋:
One difference between strsep and strtok_r is that if the input string contains more
than one character from delimiter in a row strsep returns an empty string for each
pair of characters from delimiter. This means that a program normally should test
for strsep returning an empty string before processing it.
大意是:如果輸入的串的有連續的多個字元屬於delim,(此例source中的逗號+空格,驚嘆號+空格等就是這種情況),strtok會返回NULL,而strsep會返回空串 ""。因而我們如果想用strsep函數分割字串必須進行傳回值是否是空串的判斷。這也就解釋了strsep的例子中有多個換行的原因。
改進後的代碼:
效果:
其中, 字元‘\0’ 的 10進位數為0 , 宏定義為 NULL 。
下面的說明摘自於最新的Linux核心2.6.29,說明了strtok()已經不再使用,由速度更快的strsep()代替。
/** linux/lib/string.c** Copyright (C) 1991, 1992 Linus Torvalds*/
/** stupid library routines.. The optimized versions should generally be found
* as inline code in <asm-xx/string.h>
* These are buggy as well..
* * Fri Jun 25 1999, Ingo Oeser <[email protected]>
* - Added strsep() which will replace strtok() soon (because strsep() is
* reentrant and should be faster). Use only strsep() in new code, please.
** * Sat Feb 09 2002, Jason Thomas <[email protected]>,
* Matthew Hawkins <[email protected]>
* - Kissed strtok() goodbye
*/
總結:
strsep傳回值為分割後的開始字串,並將函數的第一個參數指標指向分割後的剩餘字串。它適用於分割關鍵字在兩個字串之間只嚴格出現一次的情況。
PS:
因為函數內部會修改原字串變數,所以傳入的參數不能是不可變字串(即文字常量區)。
如 char *tokenremain ="abcdefghij"//編譯時間為文字常量,不可修改。
strtok(tokenremain,"cde");
strsep(&tokenremain,"cde");
編譯通過,運行時會報段錯誤。
C/C++ 字串分割: strtok 與 strsep 函數說明