帶你用C語言實現strtok和字符串分割函數

前言

字符串分割函數strtok,大傢可能都知道他怎麼使用,一旦要用的時候就會心生疑惑,不知道它的內部的實現,廢話不多說,本篇就來帶大傢看看strtok的基本使用和實現

一、strtok的基本使用

在這裡插入圖片描述

解析:函數大概說瞭以下幾點

1.str就是我們要去拆分的字符串,註意,我們會對該字符串進行更改,所以一般我們會拷貝一份然後去分割拷貝的那份字符串!!

2.delimiters 就是我們定義的切分的符號,假如想要用空格作為分割符,我們就可以定義 char delimiters [NUM]=” ” ** 請註意裡面放瞭一個空格的呀!!
此處NUM可以自己定義大小,這裡的delimiters 可以有多種分割方式。

3.strtok函數的第一個參數不為 NULL ,函數將找到str中第一個標記,strtok函數將會有一個設置保存他修改瞭的下一個位置的地址,如“wo ai ni”,其中若用空格作為分隔符就會將空格處換成*”\n”**,返回w的位置,並且函數內部保存a的位置。

4.strtok函數的第一個參數為 NULL ,函數將在同一個字符串中被保存的位置(即上面所說的位置w)開始,查找下一個標記。

5.如果字符串中不存在更多的標記,則返回 NULL 指針。

分析完後我們看一段代碼,對一段字符串做一個切割

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的實現

分析:進來的情況大致分為兩種,str為空和不為空的情況,函數第一次調用的話因為我們要記錄下一次進來時的位置,我們選擇在函數內部創建一個static的靜態變量,static char* p_last = NULL ,並且第一次我們設置為NULL,函數又分為兩種情況,我們切割的話用tmp指針往後走,str指針保存當前位置,所以tmp指針走到\0時我們還要將p_last處理成NULL,其他的情況(str串還能被delimiters分隔)我們就在函數內部把*tmp = ‘\0’,再將p_last處理為下一次進來的位置即可

例子:

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;
}

第一次分割

在這裡插入圖片描述

第二次分割

在這裡插入圖片描述

第三次分割

在這裡插入圖片描述

第四次切割

在這裡插入圖片描述

實現代碼如下,有需要自取:

char* my_strtok(char* str, char* delimiters)
{
	//str傳NULL的時候如果上次有記錄,則用上一次的下一個位置,不然就為NULL
    static char* p_last = NULL;
	if (str == NULL && p_last == NULL)
		return NULL;
	if (str == NULL)
	{
		//用來返回的當前位置
		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;
				}
			}
			//走到這裡表示當前的tmp沒有在delimiters中能找到的
			tmp++;
		}
		//走到這裡就是自己走到斜杠\0的位置,就要將p_last 設置成為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;
				}
			}
			//走到這裡表示當前的tmp沒有在delimiters中能找到的
			tmp++;
		}
		//找到瞭,找不到
		char* ret = p_last;
		p_last = NULL;
		return ret;
	}
}

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: