假设我正在使用strtok()
这样的..
char *token = strtok(input, ";-/");
有没有办法确定实际使用了哪个令牌?例如,如果输入类似于:
你好呀; 你好吗?/ 我很好 - 结束
我可以弄清楚每个令牌使用了哪个分隔符吗?我需要能够输出特定的消息,具体取决于令牌后面的分隔符。
重要: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);
这打印
;
/
-
编辑: 处理多个分隔符
如果您需要处理多个分隔符,确定当前分隔符序列的长度会稍微困难一些:现在您需要在确定分隔符序列有多长之前找到下一个标记。数学并不复杂,只要记住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);
你不能。strtok
用 nul 字符覆盖下一个分隔符(为了终止它这次返回的令牌),并且它不存储它覆盖的前一个值。第一次调用strtok
示例字符串时,;
就永远消失了。
如果您保留正在修改的字符串的未修改副本,则可以做一些事情strtok
- 给定当前令牌的 nul 终止符的索引(相对于字符串的开头),您可以查看副本中的相同索引看看那里有什么。
当然,这可能比编写自己的代码来分隔字符串更糟糕。您可以使用strpbrk
or strcspn
,如果您可以忍受生成的令牌不会为您终止。
男子 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);