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