在C中拆分带有多字符分隔符的char字符串

我想基于多字符分隔符拆分char *string 。 我知道strtok()用于分割字符串,但它适用于单字符分隔符。

我想基于诸如"abc"子字符串或任何其他子字符串来拆分char * string。 如何实现?

找到所需序列发生的点非常简单: strstr支持:

 char str[] = "this is abc a big abc input string abc to split up"; char *pos = strstr(str, "abc"); 

因此,在那时, pos指向较大字符串中abc的第一个位置。 事情变得有点难看。 strtok有一个令人讨厌的设计,它1)修改原始字符串,2)在内部存储指向字符串中“当前”位置的指针。

如果我们不介意大致相同,我们可以这样做:

 char *multi_tok(char *input, char *delimiter) { static char *string; if (input != NULL) string = input; if (string == NULL) return string; char *end = strstr(string, delimiter); if (end == NULL) { char *temp = string; string = NULL; return temp; } char *temp = string; *end = '\0'; string = end + strlen(delimiter); return temp; } 

这确实有效。 例如:

 int main() { char input [] = "this is abc a big abc input string abc to split up"; char *token = multi_tok(input, "abc"); while (token != NULL) { printf("%s\n", token); token = multi_tok(NULL, "abc"); } } 

产生大致预期的产量:

 this is a big input string to split up 

尽管如此,它是笨拙的,难以使线程安全(你必须使其内部string变量线程本地),通常只是一个糟糕的设计。 使用(例如)类似strtok_r的接口,我们至少可以解决线程安全问题:

 typedef char *multi_tok_t; char *multi_tok(char *input, multi_tok_t *string, char *delimiter) { if (input != NULL) *string = input; if (*string == NULL) return *string; char *end = strstr(*string, delimiter); if (end == NULL) { char *temp = *string; *string = NULL; return temp; } char *temp = *string; *end = '\0'; *string = end + strlen(delimiter); return temp; } multi_tok_t init() { return NULL; } int main() { multi_tok_t s=init(); char input [] = "this is abc a big abc input string abc to split up"; char *token = multi_tok(input, &s, "abc"); while (token != NULL) { printf("%s\n", token); token = multi_tok(NULL, &s, "abc"); } } 

我想我现在就把它留在那里 – 为了得到一个非常干净的界面,我们真的想要重新发明类似协程的东西,这可能有点多发布在这里。

您可以使用strstr()轻松编写自己的解析器来实现相同的function。 基本算法可能如下所示

  • 使用strstr()查找整个分隔符字符串的第一个匹配项
  • 标记索引
  • 从开始复制到标记的索引,这将是您的预期令牌。
  • 要解析后续条目的输入,请调整初始字符串的指示以按标记长度+分隔符字符串的长度前进。

编辑:考虑了Alan和Sourav的建议并编写了相同的基本代码。

 #include  #include  int main (void) { char str[] = "This is abc test abc string"; char* in = str; char *delim = "abc"; char *token; do { token = strstr(in,delim); if (token) *token = '\0'; printf("%s\n",in); in = token+strlen(delim); }while(token!=NULL); return 0; }