strtok函數的使用註意事項
阿新 • • 發佈:2018-01-28
由於 匹配 printf 作用 -m 結束 strtok char s sdn
其中str是要分解的字符串,delim是字符串中用來分解的字符,該函數返回分解後的字符串的起始位置指針。之所以是分解,就是說並沒有生成新的字符串,只是在源字符串上面做了一些手腳,使得源字符串發生了變化,所以一定要註意,源字符串發生了變化!!! 先從最簡單的應用來看,看下面的例1。 [cpp] view plain copy
從例1中就可以看出strtok函數的基本使用方法,輸入一個字符串數組,然後就可以將其按照一定的分隔符(例1中為".")將一個長的字符串分割成一個個短的字符串。這裏需要註意的是,在對一個長字符串分割的時候,第一次調用時,strtok函數的第一個參數傳入要分割的字符串,而第二次以及後面再次調用該函數的時候,strtok函數的第一個參數應該傳入NULL,這是因為在strtok第一個參數為NULL的時候,該函數默認使用上一次未分割完的字符串的未分割的起始位置作為本次分割的起始位置,直到分割結束為止。 這個例子就最常見的基本應用,但是僅僅知道這些很容易忽略很多細節問題,後面本文將繼續討論一些值得註意的問題。
這裏首先需要強調的是strtok函數在進行字符串分解的時候,其第一個參數,即char str[]是在變化的,就像前面說過的一樣,其只是對源字符串動了一些手腳,也就是改變了源字符串。以例1中的字符串來說,"192.168.0.26"是源字符串,在調用strtok對其分解結束後,字符串變成了"19201680026",註意其中紅色加粗部分是把‘.‘替換成了‘\0‘,也就是替換成了字符串結束標誌字符,這樣在打印或使用的時候都會使得前面的字符串成為一個看起來獨立的字符串,即"192"、"168"、"0"、"26",這些字符串還是在源字符串中,只是後面都有了自己的字符串結束標誌‘\0‘而已。
在註意事項1中提到了源字符串發生了變化,同時註意到strtok函數原型的第一個參數是一個字符數組char str[],雖然說傳遞參數時實參可以是一個指針,但是這個指針如果是字符串常量指針,那麽就會引起程序運行時崩潰,因為源字符串要發生變化,而字符串常量是不能被改變的,例如下面的例2就是錯誤的。
[cpp] view plain copy
所以如果輸入是字符串常量指針的時候,是不能直接傳遞給strtok函數的第一個參數的,大家可以將這個字符串常量指針中的內容逐一拷貝到一個字符串數組中,再進行分解,不過這種方法效率比較低,所以並不建議這樣使用,如果實在無法使用strtok函數進行字符串分解,那麽可以使用其他的函數進行類似分解,比如使用strstr函數、strchr函數等。
1. 函數原型及其基本應用
strtok函數是用來分解字符串的,其原型是: [cpp] view plain copy- char *strtok(char str[], const char *delim);
其中str是要分解的字符串,delim是字符串中用來分解的字符,該函數返回分解後的字符串的起始位置指針。之所以是分解,就是說並沒有生成新的字符串,只是在源字符串上面做了一些手腳,使得源字符串發生了變化,所以一定要註意,源字符串發生了變化!!! 先從最簡單的應用來看,看下面的例1。 [cpp] view plain copy
- // 例1
- #include <string.h>
- void main()
- {
- char s[] = "192.168.0.26";
- char *delim = ".";
- char *p;
- printf("%s ", strtok(s, delim));
- while((p = strtok(NULL, delim)))
- printf("%s ", p);
- printf("\n");
- }
從例1中就可以看出strtok函數的基本使用方法,輸入一個字符串數組,然後就可以將其按照一定的分隔符(例1中為".")將一個長的字符串分割成一個個短的字符串。這裏需要註意的是,在對一個長字符串分割的時候,第一次調用時,strtok函數的第一個參數傳入要分割的字符串,而第二次以及後面再次調用該函數的時候,strtok函數的第一個參數應該傳入NULL,這是因為在strtok第一個參數為NULL的時候,該函數默認使用上一次未分割完的字符串的未分割的起始位置作為本次分割的起始位置,直到分割結束為止。 這個例子就最常見的基本應用,但是僅僅知道這些很容易忽略很多細節問題,後面本文將繼續討論一些值得註意的問題。
2. 使用註意事項1
3. 使用註意事項2
- // 例2
- #include <string.h>
- void main()
- {
- char *s = "192.168.0.26"; // 與例1的唯一區別,字符串數組變成了字符串常量指針!!!
- char *delim = ".";
- char *p;
- printf("%s ", strtok(s, delim));
- while((p = strtok(NULL, delim)))
- printf("%s ", p);
- printf("\n");
- }
所以如果輸入是字符串常量指針的時候,是不能直接傳遞給strtok函數的第一個參數的,大家可以將這個字符串常量指針中的內容逐一拷貝到一個字符串數組中,再進行分解,不過這種方法效率比較低,所以並不建議這樣使用,如果實在無法使用strtok函數進行字符串分解,那麽可以使用其他的函數進行類似分解,比如使用strstr函數、strchr函數等。
4. 使用註意事項3
對於strtok函數的第二個參數,即分隔符,要註意:包含在delim中的字符均可以作為分隔符,而非嚴格匹配。可以把delim理解為分隔符的集合。這一點是非常重要的!當然,我們在分解字符串的時候,很少使用多個分隔符。這也導致,很多人在寫例子的時候只討論了一個分隔符的情況。有更多的人在看例子的時候也就錯誤的認識了delim的作用。5. 使用註意事項4
如果strtok函數要分解的字符串的首字符就是分隔符,那麽strtok函數會忽略第一個字符,直接從下一個分隔符算起。比如:".192.168.0.26",那麽第一個字符‘.‘就會被忽略,分解後的第一個字符串就是"192"。 總之,strtok函數是一個看起來很簡單,但是使用起來有很多需要註意的細節的函數,所以應該理解掌握,由於strtok函數並不是線程安全的,所以很多情況下並不再使用這個函數,而是由程序員實現自己的字符串分割函數,從而保證線程安全,不過,在Linux中定義了strtok_r函數,這個函數是strtok函數的線程安全版本,具體使用方法可以參考其他資料。strtok函數的使用註意事項