在 C 中复制 strtok 令牌的内容

Copying content of strtok token in C

需要分离一个字符串,然后再做另一个分离。

char *token = strtok(str, ",");
while(token){
    char *current_string = malloc(sizeof(char) * strlen(token));
    strcpy(current_string, token);

    char *tk = strtok(current_string, ":"); // KEY
    printf("key: %s ", tk);
    tk = strtok(0, ":");                    // VALUE
    printf("value: %s\r\n", tk);
    printf("%s\n", token);
    token = strtok(0, ",");
}

printf("Done\n");

试图复制 token 的内容,但这样做会弄乱 token 变量中剩余的内容。它只处理一行而不是它应该处理的三行。我怀疑问题出在 strcpy(current_string, token) 但不确定我应该如何处理它。

strtok 函数使用内部静态缓冲区来跟踪它停止的位置。这意味着您不能使用它来回解析两个不同的字符串。

在你的具体情况下,在这个电话中:

token = strtok(0, ",");

内部缓冲区仍指向 current_string 内的某个位置,因此尝试返回 token 是行不通的。

你需要strtok_r。此版本采用附加参数来跟踪当前状态。这样,您可以通过为每个字符串使用不同的状态指针来互换地解析两个或多个字符串:

char *state1, *state2;
char *token = strtok_r(str, ",", &state1);
while(token){
    char *current_string = strdup(token);

    char *tk = strtok_r(current_string, ":", &state2); // KEY
    printf("key: %s ", tk);
    tk = strtok_r(NULL, ":", &state2);                    // VALUE
    printf("value: %s\r\n", tk);
    printf("%s\n", token);
    free(current_string);
    token = strtok_r(NULL, ",", &state1);
}

printf("Done\n");

请注意,NULL 被传递给后来的 strtok_r 调用而不是 0,因为 NULL 不一定是 0。此外,对 malloc/strcpy 的调用已替换为对 strdup 的调用,后者的作用相同,并且还添加了对 free 的调用以防止内存泄漏。

strtok_r 在 UNIX/Linux 系统上可用。在 Windows 上,使用 strtok_s,其工作方式相同。