帶你用C語言實(shí)現(xiàn)strtok和字符串分割函數(shù)
前言
字符串分割函數(shù)strtok,大家可能都知道他怎么使用,一旦要用的時(shí)候就會(huì)心生疑惑,不知道它的內(nèi)部的實(shí)現(xiàn),廢話不多說,本篇就來帶大家看看strtok的基本使用和實(shí)現(xiàn)
一、strtok的基本使用
解析:函數(shù)大概說了以下幾點(diǎn)
1.str就是我們要去拆分的字符串,注意,我們會(huì)對(duì)該字符串進(jìn)行更改,所以一般我們會(huì)拷貝一份然后去分割拷貝的那份字符串??!
2.delimiters 就是我們定義的切分的符號(hào),假如想要用空格作為分割符,我們就可以定義 char delimiters [NUM]=" " ** 請(qǐng)注意里面放了一個(gè)空格的呀??!
此處NUM可以自己定義大小,這里的delimiters 可以有多種分割方式。
3.strtok函數(shù)的第一個(gè)參數(shù)不為 NULL ,函數(shù)將找到str中第一個(gè)標(biāo)記,strtok函數(shù)將會(huì)有一個(gè)設(shè)置保存他修改了的下一個(gè)位置的地址,如“wo ai ni”,其中若用空格作為分隔符就會(huì)將空格處換成*"\n"**,返回w的位置,并且函數(shù)內(nèi)部保存a的位置。
4.strtok函數(shù)的第一個(gè)參數(shù)為 NULL ,函數(shù)將在同一個(gè)字符串中被保存的位置(即上面所說的位置w)開始,查找下一個(gè)標(biāo)記。
5.如果字符串中不存在更多的標(biāo)記,則返回 NULL 指針。
分析完后我們看一段代碼,對(duì)一段字符串做一個(gè)切割
int main() { char a[] = "wo shi bo zhu"; char* retArr[10]; retArr[0] = strtok(a, " "); int i = 1; while (retArr[i++] = strtok(NULL, " ")); for (int i = 0; i < 10; i++) { printf("%s ", retArr[i]); } return 0; }
二、strtok的實(shí)現(xiàn)
分析:進(jìn)來的情況大致分為兩種,str為空和不為空的情況,函數(shù)第一次調(diào)用的話因?yàn)槲覀円涗浵乱淮芜M(jìn)來時(shí)的位置,我們選擇在函數(shù)內(nèi)部創(chuàng)建一個(gè)static的靜態(tài)變量,static char* p_last = NULL ,并且第一次我們?cè)O(shè)置為NULL,函數(shù)又分為兩種情況,我們切割的話用tmp指針往后走,str指針保存當(dāng)前位置,所以tmp指針走到\0時(shí)我們還要將p_last處理成NULL,其他的情況(str串還能被delimiters分隔)我們就在函數(shù)內(nèi)部把*tmp = ‘\0',再將p_last處理為下一次進(jìn)來的位置即可。
例子:
int main() { char a[] = "wo ai ni"; char* retArr[10]; retArr[0] = my_strtok(a, " "); int i = 1; while (retArr[i++] = my_strtok(NULL, " ")); for (int i = 0; i < 10; i++) { printf("%s ", retArr[i]); } return 0; }
第一次分割
第二次分割
第三次分割
第四次切割
實(shí)現(xiàn)代碼如下,有需要自取:
char* my_strtok(char* str, char* delimiters) { //str傳NULL的時(shí)候如果上次有記錄,則用上一次的下一個(gè)位置,不然就為NULL static char* p_last = NULL; if (str == NULL && p_last == NULL) return NULL; if (str == NULL) { //用來返回的當(dāng)前位置 str = p_last; char* tmp = p_last; int len = strlen(delimiters); while (*tmp) { for (int i = 0; i < len; ++i) { if (*tmp == delimiters[i]) { p_last = tmp+1; *tmp = '\0'; return str; } } //走到這里表示當(dāng)前的tmp沒有在delimiters中能找到的 tmp++; } //走到這里就是自己走到斜杠\0的位置,就要將p_last 設(shè)置成為NULL char* ret = p_last; p_last = NULL; return ret; } else { char* tmp = str; int len = strlen(delimiters); while (*tmp) { for (int i = 0; i < len; ++i) { if (*tmp == delimiters[i]) { p_last = tmp+1; *tmp = '\0'; return str; } } //走到這里表示當(dāng)前的tmp沒有在delimiters中能找到的 tmp++; } //找到了,找不到 char* ret = p_last; p_last = NULL; return ret; } }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(77.Combinations 組合項(xiàng))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(Combinations 組合項(xiàng)),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++ explicit關(guān)鍵字的應(yīng)用方法詳細(xì)講解
C++ explicit關(guān)鍵字用來修飾類的構(gòu)造函數(shù),表明該構(gòu)造函數(shù)是顯式的,既然有"顯式"那么必然就有"隱式",那么什么是顯示而什么又是隱式的呢?下面就讓我們一起來看看這方面的知識(shí)吧2013-09-09C++實(shí)現(xiàn)十進(jìn)制數(shù)轉(zhuǎn)為其它進(jìn)制數(shù)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)十進(jìn)制數(shù)轉(zhuǎn)為其它進(jìn)制數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C語言關(guān)鍵字auto與register的深入理解
本篇文章是對(duì)c語言關(guān)鍵字auto與register的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C語言實(shí)現(xiàn)學(xué)生選課系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)學(xué)生選課系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02Qt實(shí)現(xiàn)獲取基本網(wǎng)絡(luò)信息
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)獲取基本網(wǎng)絡(luò)信息的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04