目錄
3.關於函數傳回值的探討
5.待分解的字串,首字就為分隔符號
6.不能傳遞字串常數給第一個參數!
首頁 後端開發 C#.Net教程 strtok函數的用法是什麼

strtok函數的用法是什麼

Oct 28, 2020 am 09:48 AM
strtok函數

strtok函數的用法:1、作用於字串s,以delim中的字元為分界符,將s切分成一個子字串;2、如果s為空值NULL,則函數儲存的指標【SAVE_PTR】在下次呼叫中將作為起始位置。

strtok函數的用法是什麼

相關免費推薦:程式設計影片課程

strtok函數的用法:

##一、函數的簡介

         函數原型:char *strtok(c​​har *s, char *delim)

         功能:作用於字串s,以delim中的字元為分界符,將s切割分成一個個子字串;如果,s為空值NULL,則函數保存的指標SAVE_PTR在下AVE_PTR一次調用中將作為起始位置。

         傳回值:分隔符號符合的第一個子字串

二、主要內容

       

1、函數的功能是為#        #分解字串,所謂分解,即沒有產生新串,只是在s所指向的內容首次出現分界符的位置,將分界符修改成了'/0',故第一次用strtok()返回第一個子字串

         2、第一次提取子串完畢之後,繼續對來源字串s進行提取,應在其後(第二次,第三次。 。。第n次)的調用中將strtok的第一個參數賦為空值NULL(表示函數繼續從上   一次調用隱式保存的位置,繼續分解字符串;對於前一次次調用來說,第一次呼叫結束前用一個this指針指向了分界符的下一個

#         3、當this指針指向“\0” 時,也就是沒有分割的子字串了,此時則回傳NULL

#         4、#可以將delim理解為分隔符的集合delim中的字元皆可以作為分隔符號。

         5、strtok在呼叫的時候,如果起始位置即為分隔符,則忽略了起始位置開始的分隔符號


#三、使用strtok需要注意的有以下幾點:

1.函數的作用是分解字串,所謂分解,即沒有產生新字串,只是在s所指向的內容上做了些手腳而已。因此,來源字串s發生了變化!

設來源字串s為char buffer[INFO_MAX_SZ]=",Fred male 25,John male 62,Anna female 16";  過濾字串delim為char *delim = " ",即空格為分界符。

strtok函數的用法是什麼 

上圖的程式碼會產生這樣的結果:

strtok函數的用法是什麼

首先,buffer發生了變化。如果此時印出buffer的值,會顯示“,Fred”,而後面" male 25…16”不翼而飛了。實際上,strtok函數根據delim中的分界符,找到其首次出現的位置,即Fred後面那個空格(buffer[5]),將其修改成了'/0’。其餘位置不變。這就很好解釋為什麼印buffer的值只能出現“,Fred”,而非buffer中的全部內容了。 因此,使用strtok時一定要慎重,以防止來源字串被修改。

 

了解buffer的變化,就很好解釋函數的回傳值了。傳回值buf為分界符之前的子字串(其實這個說法並不確切,詳見"3」中對於傳回值的詳細說明)。 注意,由變數的位址可知,buf仍指向來源字串。

strtok函數的用法是什麼

分界符delim沒有發生變化,就不再截圖了。

 

2.若要在第一次提取子串完畢之後,繼續對來源字串s進行提取,應在其後(第二次,第三次。。。第n次)的調用中將strtok的第一個參數賦為空值NULL。

strtok函數的用法是什麼

####

第一次調用的結果如前文所述,提取出了",Fred」。我們也想繼續以空格為分界,提取出後面的"male」等。由上圖可以看到,第一次之後的呼叫我們都給strtok的第一個參數傳遞了空值NULL(表示函數繼續從上一次呼叫隱式保存的位置,繼續分解字串;對於上述的第二次呼叫來說,第一次呼叫結束前用一個this指標指向了分界符的下一位,即'm'所在的位置),這樣可依序提取出

strtok函數的用法是什麼# ,strtok函數的用法是什麼 。 。 。 。以此類推。 。 。 。 。

至於為什麼要賦空值,要嘛你就記得結論,要嘛去查strtok的原始碼。本文的最後會有一些介紹。

當然也有部分愛鑽牛角尖的人,非不按套路出牌,要看看不賦空值繼續賦值為buffer會有什麼結果。其實,答案想也能想的到。再一次傳遞buffer,相當於還從字串的開頭查找分界符delim,而且此時buffer已經被修改(可見的部分只剩下",Fred」),因此,其結果必然是找不到分界符delim 。

 

3.關於函數傳回值的探討

由"1」所述,在擷取到子字串的情況下,strtok的回傳值(假設回傳值賦給了指標buf)是提取出的子字串的指標。這個指標指向的是子字串在來源字串中的起始位置。子字串末尾的下一個字元在提取前為分隔符,提取後被修改成了'/0’。 因此,若列印buf的值,可以成功的輸出子字串的內容。

在沒有提取到子字串的情況下,函數會傳回什麼值呢?

strtok函數的用法是什麼

由上圖可以看到buffer中並不包含分界符delim。呼叫strtok後buf的值為

strtok函數的用法是什麼

因為沒有找到,來源字串buffer沒有改變,buf指向來源字串的首位址,列印輸出的值為整個字符串的完整值。

什麼時候函數的回傳值為空值NULL呢?

百度百科上說,「當沒有分割的字串時則回傳NULL。」這是一個很模稜兩可的說法。如果想要確切的了解清楚這個問題,可能需要看一下strtok的實作原理。這裡先以實驗說明。

strtok函數的用法是什麼

第一次呼叫strtok,毫無疑問,buf指向",Fred」。

第二次呼叫strtok,由於第一個參數為NULL,表示函數繼續以上次呼叫所儲存的this指標的位置開始分解,即對"male 25」分解。分解完畢後,buf指向"male」。

第三次呼叫strtok,參數繼續設定為NULL,此時即對第二次儲存的this指標的位置開始分解,即對"25」分解。因為無法找到包含分隔符號delim的子字串,所以buf指向"25」。

strtok函數的用法是什麼

第四次調用,參數仍為NULL,此時第三次調用保存的this指針已指向字串的末尾'/0',已無法再進行分解。因此函數傳回NULL,這也就是百度百科中所提到的「當沒有被分割的字串時函數回傳NULL。」

strtok函數的用法是什麼

## 

4 .參數分隔符delim的探討(delim是分隔符號的集合)

很多人在使用strtok的時候,都想當然的以為函數在分割字串時完整匹配分隔符號delim,例如delim=”ab ”,則對於"acdab”這個字串,函數提取出的是"acd”。至少我在第一次使用的時候也是這麼認為的。其實我們都錯了,我是在看函數的原始碼時才發現這個問題的,並且看下面的例子。

strtok函數的用法是什麼

來源字串為buffer,分隔符delim為逗號和空格,按照一般的想法我們會以為調用函數後,buf的值為"Fred,male,25 ”,結果是這樣麼?

strtok函數的用法是什麼

第一次呼叫之後的結果竟然是"Fred”,而非我們所想的結果。 這是為什麼呢?

我們回到GNU C Library中對strtok的功能定義:「Parse S into tokens separated by characters in DELIM」。 也就是說包含在delim中的字元均可以作為分隔符,而非嚴格匹配。可以把delim理解為分隔符號的集合。這一點是非常重要的~

當然,我們在分解字串的時候,很少使用多個分隔符號。這也導致,很多人在寫例子的時候只討論了一個分隔符號的情況。有更多的人在看例子的時候也就錯誤的認識了delim的作用。

5.待分解的字串,首字就為分隔符號

首字不能算是一個很特殊的情況。按照常規的分解思路也能正確分解字串。

我想說明的是,strtok對於這種情況採用了比常規處理更快的方式。

strtok函數的用法是什麼

如上圖範例所示。僅用一次呼叫就可以得到以逗號分隔的字串"Fred male 25”,而F前面的','被忽略了。由此可見,strtok在呼叫的時候忽略了起始位置開始的分隔符號。 這一點,可以從strtok的原始碼得到證實。

6.不能傳遞字串常數給第一個參數!

本文所舉的例子都將來源字串儲存為字串陣列變數。若你將來源字串定義成字串常數,可想而知,程式會因為strtok函數試圖修改來源字串的值,而拋出異常。

strtok函數的用法是什麼

#

以上是strtok函數的用法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

C語言各種符號的使用方法 C語言各種符號的使用方法 Apr 03, 2025 pm 04:48 PM

C 語言中符號的使用方法涵蓋算術、賦值、條件、邏輯、位運算符等。算術運算符用於基本數學運算,賦值運算符用於賦值和加減乘除賦值,條件運算符用於根據條件執行不同操作,邏輯運算符用於邏輯操作,位運算符用於位級操作,特殊常量用於表示空指針、文件結束標記和非數字值。

char在C語言字符串中的作用是什麼 char在C語言字符串中的作用是什麼 Apr 03, 2025 pm 03:15 PM

在 C 語言中,char 類型在字符串中用於:1. 存儲單個字符;2. 使用數組表示字符串並以 null 終止符結束;3. 通過字符串操作函數進行操作;4. 從鍵盤讀取或輸出字符串。

char在C語言中如何處理特殊字符 char在C語言中如何處理特殊字符 Apr 03, 2025 pm 03:18 PM

C語言中通過轉義序列處理特殊字符,如:\n表示換行符。 \t表示製表符。使用轉義序列或字符常量表示特殊字符,如char c = '\n'。注意,反斜杠需要轉義兩次。不同平台和編譯器可能有不同的轉義序列,請查閱文檔。

c#多線程和異步的區別 c#多線程和異步的區別 Apr 03, 2025 pm 02:57 PM

多線程和異步的區別在於,多線程同時執行多個線程,而異步在不阻塞當前線程的情況下執行操作。多線程用於計算密集型任務,而異步用於用戶交互操作。多線程的優勢是提高計算性能,異步的優勢是不阻塞 UI 線程。選擇多線程還是異步取決於任務性質:計算密集型任務使用多線程,與外部資源交互且需要保持 UI 響應的任務使用異步。

char與wchar_t在C語言中的區別 char與wchar_t在C語言中的區別 Apr 03, 2025 pm 03:09 PM

在 C 語言中,char 和 wchar_t 的主要區別在於字符編碼:char 使用 ASCII 或擴展 ASCII,wchar_t 使用 Unicode;char 佔用 1-2 個字節,wchar_t 佔用 2-4 個字節;char 適用於英語文本,wchar_t 適用於多語言文本;char 廣泛支持,wchar_t 依賴於編譯器和操作系統是否支持 Unicode;char 的字符範圍受限,wchar_t 的字符範圍更大,並使用專門的函數進行算術運算。

char在C語言中如何進行類型轉換 char在C語言中如何進行類型轉換 Apr 03, 2025 pm 03:21 PM

在 C 語言中,char 類型轉換可以通過:強制類型轉換:使用強制類型轉換符將一種類型的數據直接轉換為另一種類型。自動類型轉換:當一種類型的數據可以容納另一種類型的值時,編譯器自動進行轉換。

char和unsigned char的區別是什麼 char和unsigned char的區別是什麼 Apr 03, 2025 pm 03:36 PM

char 和 unsigned char 是存儲字符數據的兩種數據類型,主要區別在於處理負數和正數的方式:值範圍:char 有符號 (-128 到 127),unsigned char 無符號 (0 到 255)。負數處理:char 可以存儲負數,unsigned char 不能。位模式:char 最高位表示符號,unsigned char 無符號位。算術運算:char 和 unsigned char 作為有符號和無符號類型,其算術運算方式不同。兼容性:char 和 unsigned char

char數組在C語言中如何使用 char數組在C語言中如何使用 Apr 03, 2025 pm 03:24 PM

char 數組在 C 語言中存儲字符序列,聲明為 char array_name[size]。訪問元素通過下標運算符,元素以空終止符 '\0' 結尾,用於表示字符串終點。 C 語言提供多種字符串操作函數,如 strlen()、strcpy()、strcat() 和 strcmp()。

See all articles