C语言字符串分割函数split实现

参考了到处是“坑”的strtok()—解读strtok()的隐含特性这一篇博文, 概括来说C语言在string.h中的strtok()有以下几个坑:

  1. 不可重入
  2. 原字符串被修改
  3. 连续的分隔符被当做一个分隔符处理
  4. 忽略开头结尾的分隔符
不过怎么说多多少少有些缺陷,用起来不是很满意,因此自己动手实现了一个类似java中split的字符串分割函数,如下:
#include 
#include 
#include 
/*
用delimiter中的每一个分隔符分割str字符串,这并不会改变str中的字符,然后返回一个字符串数组.
字符串数组中的字符串有可能是以'\0'开头的空串(出现在str首尾或连续的分隔符会产生这样的空串).
这个函数有以下特性:
	支持多线程,可重入的;
	不会修改原字符串;
	能处理首尾和连续的分隔符.
返回:以NULL为结束标志的字符串数组.
*/
char** split(char *str, char *delimiter) {
	int len = strlen(str);
	char *strCopy = (char*)malloc((len + 1) * sizeof(char)); //额外分配多一个字符空间来存储'\0'
	strcpy(strCopy, str); //复制str字符串
	//将strCopy中的每个分隔符赋值为'\0'
	for (int i = 0; strCopy[i] != '\0'; i++) {
		for (int j = 0; delimiter[j] != '\0'; j++) {
			if (strCopy[i] == delimiter[j]) {
				strCopy[i] = '\0';
				break;
			}
		}
	}
	//为字符串数组分配空间,额外分配多一个字符串指针并赋值为NULL来作为字符串结束标志
	char** res = (char**)malloc((len + 2) * sizeof(char*)); 
	len++; //遍历到strCopy最后的'\0'才结束
	int resI = 0; //每一个分隔符和原字符串的'\0'标志依次作为数组中的字符串的结束标志
	for (int i = 0; i < len; i++) {
		res[resI++] = strCopy + i;
		while (strCopy[i] != '\0') {
			i++;
		}
	}
	res[resI] = NULL; //字符串数组中结束标志


	return res;
}
int main() {
	//split测试数据
	char strs[][40] = {
		{""},
		{"apple"},
		{"app@le"},
		{"ap@pl&e"},
		{"@"},
		{"app@@le"},
		{"@apple@"}
	};


	for (int i = 0; i < 7; i++) {
		char **res = split(strs[i], (char*)"@&");
		for (int j = 0; res[j] != NULL; j++) {
			printf("%s\n", res[j]);
		}
		printf("**************\n");
	}


	return 0;
}

测试效果:

C语言字符串分割函数split实现_第1张图片

你可能感兴趣的:(C)