众所周知,标准的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。