Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
117 views
in Technique[技术] by (71.8m points)

Nested strtok function problem in C


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You cannot do that with strtok(); use strtok_r() from POSIX or strtok_s() from Microsoft if they are available, or rethink your design.

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

These two functions are interchangeable.

Note that a variant strtok_s() is specified in an optional part of C11 (Annex K in ISO/IEC 9899:2011). However, few suppliers other than Microsoft have implemented the interfaces in that section of the standard. The version of strtok_s() specified in Annex K has a different interface from Microsoft's strtok_s() — similar problems bedevil a number of the other functions specified in Annex K.

With strtok_r()

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

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

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

    return 0;
}

Results

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

Without strtok_r()

This works in context - provided that the data ends with a newline.

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

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

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

    return 0;
}

Output

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...