在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; }