C/C++ 字串分割: strtok 與 strsep 函數說明

來源:互聯網
上載者:User

標籤: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 函數說明

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.