代码之家  ›  专栏  ›  技术社区  ›  Bdfy

如何安全分析制表符分隔的字符串?

  •  0
  • Bdfy  · 技术社区  · 14 年前

    如何安全分析制表符分隔符字符串?例如: 测试\tbla bla bla \t2332?

    6 回复  |  直到 10 年前
        1
  •  5
  •   DevSolar    14 年前

    strtok() 是用任意分隔符分析字符串的标准函数。但是,它不是线程安全的。您选择的C库可能有一个线程安全的变体。

    另一个符合标准的方法 未试验过 ):

    #include <string.h>
    #include <stdio.h>
    
    int main()
    {
        char string[] = "foo\tbar\tbaz";
        char * start = string;
        char * end;
        while ( ( end = strchr( start, '\t' ) ) != NULL )
        {
            // %s prints a number of characters, * takes number from stack
            // (your token is not zero-terminated!)
            printf( "%.*s\n", end - start, start );
            start = end + 1;
        }
        // start points to last token, zero-terminated
        printf( "%s", start );
        return 0;
    }
    
        2
  •  4
  •   Ziffusion    14 年前

    使用strtok_r而不是strtok(如果有)。它有类似的用法,只是它是可重入的,并且 没有 像strtok那样修改字符串。[ 编辑: 实际上,我说错了。正如克里斯托夫指出的,strtok_r确实用'\0'替换了定界符。因此,如果要保留原始字符串,应该对字符串的副本进行操作。但它比strtok更可取,因为它是可重入的,并且线程安全]

    strtok将修改原始字符串。它将分隔符替换为'\0'。如果您的字符串恰好是一个常量,存储在只读内存中(有些编译器会这样做),那么实际上您可能会遇到访问冲突。

        3
  •  2
  •   k_g    10 年前

    使用 strtok() string.h .

    #include <stdio.h>
    #include <string.h>
    
    int main ()
    {
        char str[] = "test\tbla-bla-bla\t2332";
        char * pch;
        pch = strtok (str," \t");
        while (pch != NULL)
        {
            printf ("%s\n",pch);
            pch = strtok (NULL, " \t");
        }
        return 0;
    }
    
        4
  •  0
  •   Tarantula    14 年前

    你可以使用任何regex库甚至glib GScanner here here 更多信息。

        5
  •  0
  •   Christoph    14 年前

    另一个版本;这个版本将逻辑分解为一个新的函数

    #include <stdio.h>
    
    static _Bool next_token(const char **start, const char **end)
    {
        if(!*end) *end = *start;    // first call
        else if(!**end)             // check for terminating zero
            return 0;
        else *start = ++*end;       // skip tab
    
        // advance to terminating zero or next tab
        while(**end && **end != '\t')
            ++*end;
    
        return 1;
    }
    
    int main(void)
    {
        const char *string = "foo\tbar\tbaz";
    
        const char *start = string;
        const char *end = NULL; // NULL value indicates first call
    
        while(next_token(&start, &end))
        {
            // print substring [start,end[
            printf("%.*s\n", end - start, start);
        }
    
        return 0;
    }
    
        6
  •  0
  •   JaÍ¢ck    11 年前

    如果需要二进制安全方法来标记给定的字符串:

    #include <string.h>
    #include <stdio.h>
    
    void tokenize(const char *str, const char delim, const size_t size)
    {
            const char *start = str, *next;
            const char *end = str + size;
    
            while (start < end) {
                    if ((next = memchr(start, delim, end - start)) == NULL) {
                            next = end;
                    }
    
                    printf("%.*s\n", next - start, start);
                    start = next + 1;
            }
    }
    
    int main(void)
    {
            char str[] = "test\tbla-bla-bla\t2332";
            int len = strlen(str);
    
            tokenize(str, '\t', len);
    
            return 0;
    }