【问题标题】:Split string into tokens and save them in an array将字符串拆分为标记并将它们保存在数组中
【发布时间】:2013-03-06 12:32:13
【问题描述】:

如何将字符串拆分成token,然后保存到数组中?

具体来说,我有一个字符串"abc/qwe/jkh"。我想将"/"分开,然后将令牌保存到一个数组中。

输出将是这样的

array[0] = "abc"
array[1] = "qwe"
array[2] = "jkh"

请帮帮我

【问题讨论】:

    标签: c split strtok


    【解决方案1】:

    您可以使用strtok()

    char string[]=  "abc/qwe/jkh";
    char *array[10];
    int i=0;
    
    array[i] = strtok(string,"/");
    
    while(array[i]!=NULL)
    {
       array[++i] = strtok(NULL,"/");
    }
    

    【讨论】:

    • 可以将空指针指定为 strtok() 的第一个参数,在这种情况下,函数会继续扫描之前成功调用函数的位置。
    • 工作得很好。如果我们不知道 slpit 元素的数量,如何给出动态计数..
    • 不能用变量初始化数组吗?
    • 这会将4个元素放入数组中,最后一个为NULL。
    • strtok() 不是一个好的解决方案,因为它需要不在堆栈或堆上的变量。
    【解决方案2】:
    #include <stdio.h>
    #include <string.h>
    
    int main ()
    {
        char buf[] ="abc/qwe/ccd";
        int i = 0;
        char *p = strtok (buf, "/");
        char *array[3];
    
        while (p != NULL)
        {
            array[i++] = p;
            p = strtok (NULL, "/");
        }
    
        for (i = 0; i < 3; ++i) 
            printf("%s\n", array[i]);
    
        return 0;
    }
    

    【讨论】:

    • 如果我想比较数组[0]和数组[1],我应该怎么做?
    • 你使用 中的另一个函数: if (strcmp(array[0], array[1]) == 0) { // array[0] = array[1] }
    • 这假设令牌的数量是已知的。
    • p = strtok (NULL, "/");这行的目的是什么?
    • strtok() 在多线程程序、库或其他一些程序中不能很好地工作,这些程序可能会使用不同的字符串第二次调用 strtok() 而之前没有完成循环。 strtok_r() 可能是更好的解决方案,或者当 strtok_r() 不可用时编写自己的函数。
    【解决方案3】:

    为什么strtok() 是个坏主意

    不要在普通代码中使用strtok()strtok() 使用static 变量会有一些问题。在嵌入式微控制器上有一些用例,其中static 变量有意义,但在大多数其他情况下避免使用它们。 strtok() 在超过 1 个线程使用它、在中断中使用它或在某些其他情况下(在对 strtok() 的连续调用之间处理多个输入的其他情况下)表现出意外。 考虑这个例子:

    #include <stdio.h>
    #include <string.h>
    
    //Splits the input by the / character and prints the content in between
    //the / character. The input string will be changed
    void printContent(char *input)
    {
        char *p = strtok(input, "/");
        while(p)
        {
            printf("%s, ",p);
            p = strtok(NULL, "/");
        }
    }
    
    int main(void)
    {
        char buffer[] = "abc/def/ghi:ABC/DEF/GHI";
        char *p = strtok(buffer, ":");
        while(p)
        {
            printContent(p);
            puts(""); //print newline
            p = strtok(NULL, ":");
        }
        return 0;
    }
    

    你可能期望输出:

    abc, def, ghi,
    ABC, DEF, GHI,
    

    但你会得到

    abc, def, ghi,
    

    这是因为你在printContent() 中调用strtok() 是因为在main() 中生成strtok() 的内部状态。返回后strtok()的内容为空,下次调用strtok()返回NULL

    你应该怎么做

    使用 POSIX 系统时可以使用strtok_r(),此版本不需要static 变量。如果您的库不提供strtok_r(),您可以编写自己的版本。这应该不难,而且 Stackoverflow 不是编码服务,你可以自己写。

    【讨论】:

    • OP 从未提到他们处于多线程环境中
    • @sijanec 他也没有说他不是。请记住,库应该是多线程保存的,并且在库中放置 strtok() 是一个坏主意。正如我在回答中所写的,这不仅是多线程应用程序中的问题。评论前请阅读,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多