C语言用二级指针实现以字符串为分割符的函数-加强版strtok

众所周知,标准的c有字符分割功能函数大致:

char *strstr(const char *haystack, const char *needle);

在字符串 haystack 中查找第一次出现字符串 needle(不包含空结束字符)的位置。

char *strchr(const char *str, int c)

在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。

char *strtok(char *str, const char *delim)

分解字符串 str 为一组字符串,delim 为分隔符

int sscanf (char *str, char * format [, argument, ...]);

参数str 的字符串根据参数format(格式化字符串)来转换并格式化数据(格式化字符串请参考scanf()), 转换后的结果存于对应的变量中。

以上都是比较常用的字符串分割手段,一般的字符串处理已经没有难点了, 但是却都有其局限性,假如给出这样一种场景,一个未知长度的字符串,以标准格式排列,你需要以特定的字符串一一进行分割处理, 这时以上函数都很难做到了:

char *tmp = strtok(str, slip); 
while(tmp !=  NULl){
tmp = strtok(NULL, slip);
}

用strtok循环处理分割时, 无法处理以字符串分割的方式,它是以单字符进行一个处理,这个原因与其源码实现有关,里面内置的static没有包含字符串处理手段,这种情况通常需要自己结合基本字符串调用去实现, 以下是我实现的例子:

char** MyStrSplit(const char* string,const char* split)
{
	char** result;
	/*malloc for result*/
	result = (char * * )malloc(sizeof(char *)*1);
	memset(result,0,sizeof(char *)*1);
	/*遍历用的指针 P 和寻找位置用的指针 pos*/
	char* p = (void *)string;
	char* pos = (void *)string;
	int count = 1;
	while(*p != '\0')
	{
		char* temp;
		char* t_temp;
		pos = strstr(p,split);
        printf("[test][%d] pos : %s \n", __LINE__, pos);
		if(pos == 0)
		{
			result = (char * * )realloc(result,sizeof(char *)*(count + 2));
			//result[0] = count;
			result[count] = p;
			result[count + 1] = NULL;
			return result;
		}
		temp = (char * )malloc(sizeof(char)*(pos - p + 1));
		memset(temp,0,sizeof(char)*(pos - p + 1));
		t_temp= temp;
		while(p <= pos)
		{
			*temp++ = *p++;
		}
		*--temp = '\0';
		result = (char * * )realloc(result,sizeof(char *)*(count + 1));
		//result[0] = count;
		result[count] = t_temp;
        printf("[test][%d] t_temp: %s \n", __LINE__, t_temp);
		count++;
		/*注意需要设置下一次遍历时的指针*/
		p += strlen(split) - 1;
        printf("[test][%d] last p: %s \n", __LINE__, p);
	}
	return result;
}
int i = 1; //注意这里是1,上面函数实现时兼容跳过了0
char **tmp = StringSplit(str, slip);
    while(*(tmp + i) != NULL){
    printf("%s \n ", *(tmp + i));  //这里既是分割出来的字符块
}

初步验证OK。

Guess you like

Origin blog.csdn.net/huang422600/article/details/121131626