strtok函數(shù)如何使用?這個(gè)問題可能是我們?nèi)粘W(xué)習(xí)或工作經(jīng)常見到的。希望通過這個(gè)問題能讓你收獲頗深。下面是小編給大家?guī)淼膮⒖純?nèi)容,讓我們一起來看看吧!
成都創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),涪城網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:涪城等地區(qū)。涪城做網(wǎng)站價(jià)格咨詢:18982081108strtok函數(shù)的用法:1、作用于字符串s,以delim中的字符為分界符,將s切分成一個(gè)個(gè)子串;2、如果s為空值NULL,則函數(shù)保存的指針【SAVE_PTR】在下一次調(diào)用中將作為起始位置。
strtok函數(shù)的用法:
一、函數(shù)的簡(jiǎn)介
函數(shù)原型:char *strtok(char *s, char *delim)
功能:作用于字符串s,以delim中的字符為分界符,將s切分成一個(gè)個(gè)子串;如果,s為空值NULL,則函數(shù)保存的指針SAVE_PTR在下一次調(diào)用中將作為起始位置。
返回值:分隔符匹配到的第一個(gè)子串
二、主要內(nèi)容
1、函數(shù)的作用是分解字符串,所謂分解,即沒有生成新串,只是在s所指向的內(nèi)容首次出現(xiàn)分界符的位置,將分界符修改成了'/0’,故第一次用strtok()返回第一個(gè)子串
2、第一次提取子串完畢之后,繼續(xù)對(duì)源字符串s進(jìn)行提取,應(yīng)在其后(第二次,第三次。。。第n次)的調(diào)用中將strtok的第一個(gè)參數(shù)賦為空值NULL(表示函數(shù)繼續(xù)從上 一次調(diào)用隱式保存的位置,繼續(xù)分解字符串;對(duì)于前一次次調(diào)用來說,第一次調(diào)用結(jié)束前用一個(gè)this指針指向了分界符的下一位)
3、當(dāng)this指針指向“\0” 時(shí),即沒有被分割的子串了,此時(shí)則返回NULL
4、可以把delim理解為分隔符的集合,delim中的字符均可以作為分隔符。
5、strtok在調(diào)用的時(shí)候,如果起始位置即為分隔符,則忽略了起始位置開始的分隔符
三、使用strtok需要注意的有以下幾點(diǎn):
設(shè)源字符串s為 char buffer[INFO_MAX_SZ]=",Fred male 25,John male 62,Anna female 16"; 過濾字符串delim為 char *delim = " ",即空格為分界符。
上圖的代碼會(huì)產(chǎn)生這樣的結(jié)果:
首先,buffer發(fā)生了變化。如果此時(shí)打印buffer的值,會(huì)顯示“,Fred”,而后面" male 25…16”不翼而飛了。實(shí)際上,strtok函數(shù)根據(jù)delim中的分界符,找到其首次出現(xiàn)的位置,即Fred后面那個(gè)空格(buffer[5]),將其修改成了'/0’。其余位置不變。這就很好解釋為什么打印buffer的值只能出現(xiàn)“,Fred”,而非buffer中的全部?jī)?nèi)容了。因此,使用strtok時(shí)一定要慎重,以防止源字符串被修改。
理解了buffer的變化,就很好解釋函數(shù)的返回值了。返回值buf為分界符之前的子串(其實(shí)這個(gè)說法并不確切,詳見"3”中對(duì)于返回值的詳細(xì)說明)。注意,由變量的地址可知,buf依然指向源字符串。
分界符delim沒有發(fā)生變化,就不再截圖了。
第一次調(diào)用的結(jié)果如前文所述,提取出了",Fred”。我們還想繼續(xù)以空格為分界,提取出后面的"male”等。由上圖可以看到,第一次之后的調(diào)用我們都給strtok的第一個(gè)參數(shù)傳遞了空值NULL(表示函數(shù)繼續(xù)從上一次調(diào)用隱式保存的位置,繼續(xù)分解字符串;對(duì)于上述的第二次調(diào)用來說,第一次調(diào)用結(jié)束前用一個(gè)this指針指向了分界符的下一位,即'm’所在的位置),這樣可依次提取出
, 。。。。以此類推。。。。。
至于為什么要賦空值,要么你就記住結(jié)論,要么去查strtok的源代碼。本文的最后會(huì)有一些介紹。
當(dāng)然也有部分愛鉆牛角尖的人,非不按套路出牌,要看看不賦空值繼續(xù)賦值為buffer會(huì)有什么結(jié)果。其實(shí),答案想也能想的到。再一次傳遞buffer,相當(dāng)于還從字符串的開頭查找分界符delim,而且此時(shí)buffer已經(jīng)被修改(可見的部分只剩下",Fred”),因此,其結(jié)果必然是找不到分界符delim。
由"1”中所述,在提取到子串的情況下,strtok的返回值(假設(shè)返回值賦給了指針buf)是提取出的子串的指針。這個(gè)指針指向的是子串在源字符串中的起始位置。子串末尾的下一個(gè)字符在提取前為分隔符,提取后被修改成了'/0’。因此,若打印buf的值,可以成功的輸出子串的內(nèi)容。
在沒有提取到子串的情況下,函數(shù)會(huì)返回什么值呢?
由上圖可以看到buffer中并不包含分界符delim。調(diào)用strtok后buf的值為
因?yàn)闆]有找到,源字符串buffer沒有發(fā)生改變,buf指向源字符串的首地址,打印輸出的值為整個(gè)字符串的完整值。
什么時(shí)候函數(shù)的返回值為空值NULL呢?
百度百科上說,“當(dāng)沒有被分割的串時(shí)則返回NULL。”這是一個(gè)很模棱兩可的說法。如果想要確切的了解清楚這個(gè)問題,可能需要看一下strtok的實(shí)現(xiàn)原理。這里先以實(shí)驗(yàn)說明。
第一次調(diào)用strtok,毫無疑問,buf指向",Fred”。
第二次調(diào)用strtok,由于第一個(gè)參數(shù)為NULL,表示函數(shù)繼續(xù)以上次調(diào)用所保存的this指針的位置開始分解,即對(duì)"male 25”分解。分解完畢后,buf指向"male”。
第三次調(diào)用strtok,參數(shù)繼續(xù)設(shè)定為NULL,此時(shí)即對(duì)第二次保存的this指針的位置開始分解,即對(duì)"25”分解。因?yàn)闊o法找到包含分隔符delim的子串,所以buf指向"25”。
第四次調(diào)用,參數(shù)仍為NULL,此時(shí)第三次調(diào)用保存的this指針已指向字符串的末尾'/0’,已無法再進(jìn)行分解。因此函數(shù)返回NULL,這也就是百度百科中所提到的“當(dāng)沒有被分割的串時(shí)函數(shù)返回NULL?!?/p>
很多人在使用strtok的時(shí)候,都想當(dāng)然的以為函數(shù)在分割字符串時(shí)完整匹配分隔符delim,比如delim=”ab”,則對(duì)于"acdab”這個(gè)字符串,函數(shù)提取出的是"acd”。至少我在第一次使用的時(shí)候也是這么認(rèn)為的。其實(shí)我們都錯(cuò)了,我是在看函數(shù)的源代碼時(shí)才發(fā)現(xiàn)這個(gè)問題的,且看下面的例子。
源字符串為buffer,分隔符delim為 逗號(hào)和空格,按照一般的想法我們會(huì)以為調(diào)用函數(shù)后,buf的值為"Fred,male,25”,結(jié)果是這樣么?
第一次調(diào)用之后的結(jié)果竟然是"Fred”,而非我們所想的結(jié)果。這是為什么呢?
我們回到GNU C Library中對(duì)strtok的功能定義:“Parse S into tokens separated by characters in DELIM”。也就是說包含在delim中的字符均可以作為分隔符,而非嚴(yán)格匹配??梢园裠elim理解為分隔符的集合。這一點(diǎn)是非常重要的~
當(dāng)然,我們?cè)诜纸庾址臅r(shí)候,很少使用多個(gè)分隔符。這也導(dǎo)致,很多人在寫例子的時(shí)候只討論了一個(gè)分隔符的情況。有更多的人在看例子的時(shí)候也就錯(cuò)誤的認(rèn)識(shí)了delim的作用。
首字符為分隔符不能算作一個(gè)很特殊的情況。按照常規(guī)的分解思路也能正確分解字符串。
我想說明的是,strtok對(duì)于這種情況采用了比常規(guī)處理更快的方式。
如上圖例子所示。僅用一次調(diào)用就可以得到以逗號(hào)分隔的字符串"Fred male 25”,而F前面的','被忽略了。由此可見,strtok在調(diào)用的時(shí)候忽略了起始位置開始的分隔符。這一點(diǎn),可以從strtok的源代碼得到證實(shí)。
本文中所舉的例子都將源字符串保存為字符串?dāng)?shù)組變量。若你將源字符串定義成字符串常量,可想而知,程序會(huì)因?yàn)閟trtok函數(shù)試圖修改源字符串的值,而拋出異常。
感謝各位的閱讀!看完上述內(nèi)容,你們對(duì)strtok函數(shù)如何使用大概了解了嗎?希望文章內(nèi)容對(duì)大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道。