假设我正在像这样使用strtok()
..
char *token = strtok(input, ";-/");
有没有办法找出实际使用的令牌?例如,如果输入如下:
Hello there; How are you? / I'm good - End
我能否找出用于每个令牌的定界符?我需要能够根据跟随令牌的定界符输出特定消息。
重要提示: 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);
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);
strsep
不属于 C 或 Posix(尽管strtok_r
属于 Posix,strtok_s
属于 C11),但它属于 LSB 和 BSD。因此,在某些系统上,strtok
已被strsep
废弃,而在其他系统上则没有。关于 man 手册的事情是,它们只适用于运行man
的系统。 - Steve Jessop