c - C中的嵌套strtok函数问题

标签 c nested token tokenize strtok

我有一个像这样的字符串:

a;b;c;d;e
f;g;h;i;j
1;2;3;4;5

我想逐个元素地解析它。我使用了嵌套的 strtok 函数,但它只是分割第一行并使 token 指针为空。我怎样才能克服这个问题?这是代码:

token = strtok(str, "\n");

while(token != NULL && *token != EOF)
{
    char a[128], b[128];
    strcpy(a,token);
    strcpy(b,a);
    printf("a:%s\n",a);
    char *token2 = strtok(a,";");
    while(token2 != NULL)
    {
        printf("token2 %s\n",token2);
        token2 = strtok(NULL,";");
    }
    strcpy(token,b);
    token = strtok(NULL, "\n");
    if(token == NULL)
    {
        printf("its null");
    }
}

输出:

token 2 a
token 2 b
token 2 c
token 2 d
token 2 e

最佳答案

你不能用strtok()来做到这一点;使用strtok_r()来自 POSIX 或 strtok_s()来自 Microsoft(如果可用),或者重新考虑您的设计。

char *strtok_r(char *restrict s, const char *restrict sep,
               char **restrict lasts);
char *strtok_s(char *strToken, const char *strDelimit, char **context); 

这两个函数是可以互换的。

请注意,一个变体 strtok_s()在 C11 的可选部分中指定(ISO/IEC 9899:2011 中的附录 K)。然而,除了 Microsoft 之外,很少有供应商实现了该标准该部分中的接口(interface)。附件 K 中指定的 strtok_s() 版本与 Microsoft 的 strtok_s() 具有不同的接口(interface) - 类似的问题困扰着附件 K 中指定的许多其他函数。

使用 strtok_r()

#include <string.h>
#include <stdio.h>

int main(void)
{
    char str[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n";
    char *end_str;
    char *token = strtok_r(str, "\n", &end_str);

    while (token != NULL)
    {
        char *end_token;
        printf("a = %s\n", token);
        char *token2 = strtok_r(token, ";", &end_token);
        while (token2 != NULL)
        {
            printf("b = %s\n", token2);
            token2 = strtok_r(NULL, ";", &end_token);
        }
        token = strtok_r(NULL, "\n", &end_str);
    }

    return 0;
}

结果

a = a;b;c;d;e
b = a
b = b
b = c
b = d
b = e
a = f;g;h;i;j
b = f
b = g
b = h
b = i
b = j
a = 1;2;3;4;5
b = 1
b = 2
b = 3
b = 4
b = 5

没有 strtok_r()

这在上下文中有效 - 前提是数据以换行符结尾。

#include <string.h>
#include <stdio.h>

int main(void)
{
    char data[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n";
    char *string = data;
    char *token  = strchr(string, '\n');

    while (token != NULL)
    {
        /* String to scan is in string..token */
        *token++ = '\0';
        printf("a = %s\n", string);
        char *token2 = strtok(string, ";");
        while (token2 != NULL)
        {
            printf("b = %s\n", token2);
            token2 = strtok(NULL, ";");
        }
        string = token;
        token = strchr(string, '\n');
    }

    return 0;
}

输出

a = a;b;c;d;e
b = a
b = b
b = c
b = d
b = e
a = f;g;h;i;j
b = f
b = g
b = h
b = i
b = j
a = 1;2;3;4;5
b = 1
b = 2
b = 3
b = 4
b = 5

关于c - C中的嵌套strtok函数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43480124/

相关文章:

有人可以帮我用 C 语言进行此前向声明吗?

c - 为什么这个动态加载的库不能访问加载程序的全局变量?

c - fork 后调试子进程(follow-fork-mode child 配置)

mysql - 如何计算类别中的产品

c - 来自用户的 n 个整数的中位数

php - mysql中的嵌套表

javascript - 在 .then 函数中返回嵌套在 forEach 中的 Promise

ios - 检索已经获取的推送通知 token

C 计数标记

Botframework 网络聊天的 token 生成