C - 确定使用哪个分隔符 - strtok()

时间:2012-09-17 13:28:16

标签: c tokenize strtok

假设我正在使用这样的strtok() ..

char *token = strtok(input, ";-/");

有没有办法找出实际使用哪个令牌?例如,如果输入类似于:

Hello there; How are you? / I'm good - End

我可以找出每个令牌使用哪个分隔符吗?我需要能够输出特定的消息,具体取决于令牌后面的分隔符。

3 个答案:

答案 0 :(得分:9)

重要提示:strtok不可重入,您应该使用strtok_r代替它。

您可以通过保存原始字符串的副本,并查看当前令牌到该副本的偏移量来实现:

char str[] = "Hello there; How are you? / I'm good - End";
char *copy = strdup(str);
char *delim = ";-/";
char *res = strtok( str, delim );
while (res) {
    printf("%c\n", copy[res-str+strlen(res)]);
    res = strtok( NULL, delim );
}
free(copy);

打印

;
/
-

Demo #1

编辑: 处理多个分隔符

如果需要处理多个分隔符,确定当前分隔符序列的长度会变得稍微困难​​:现在需要在确定分隔符序列的长度之前找到下一个标记。数学并不复杂,只要你记得NULL需要特殊处理:

char str[] = "(20*(5+(7*2)))+((2+8)*(3+6*9))";
char *copy = strdup(str);
char *delim = "*+()";
char *res = strtok( str, delim );
while (res) {
    int from = res-str+strlen(res);
    res = strtok( NULL, delim );
    int to = res != NULL ? res-str : strlen(copy);
    printf("%.*s\n", to-from, copy+from);
}
free(copy);

Demo #2

答案 1 :(得分:3)

你做不到。 strtok用nul字符覆盖下一个分隔符(为了终止它此次返回的标记),它不存储它覆盖的先前值。第一次在示例字符串上调用strtok时,;将永远消失。

如果您使用strtok保留正在修改的字符串的未修改副本,则可以执行某些操作 - 给定当前标记的nul终止符的索引(相对于字符串的开头),您可以查看副本中的相同索引,看看那里有什么。

当然,这可能比编写自己的代码来分隔字符串更糟糕。您可以使用strpbrkstrcspn,如果您可以使用生成的令牌而不是为您终止。

答案 2 :(得分:1)

  

man 3 strtok

     

strtok()和strtok_r()函数返回一个指针   更换后,字符串中每个后续标记的开头   令牌本身带有NUL字符。什么时候没有        剩下更多的标记,返回空指针。

但是通过一个小指针算法,您可以执行以下操作:

char* string = "Hello,World!";
char* dup = strdup(string);

char* world = strtok(string, ",");
char delim_used = dup[world - string];

free(dup);