Parallel to PHP's “explode” in C: Split char* into char* using delimiter [duplicate]

左心房为你撑大大i 提交于 2019-12-08 01:27:25

You can use strtok like CrazyCasta said but his/hers code is wrong.

char *tok;
char *src = malloc(strlen(srcStr) + 1);
memcpy(src, srcStr);

tok = strtok(src, "#");
if(tok == NULL)
{
    printf("no tokens found");
    free(src);
    return ???;
}
printf("%s ; ", tok);
while((tok = strtok(NULL, "#")))
    printf("%s ; ", tok);
printf("\n");
free(str);

Be aware that strtok has to be called the first time with the source pointer, after that you have to use NULL. Also src must be writeable because strtok writes \0 to terminate the found strings. Hence, depending on how you read the string (and whether you are going to use it afterwards or not), you should do a copy of it. But as I said, this is not always necessary.

EDIT:

an explode function could look like this:

char *strdup(const char *src)
{
    char *tmp = malloc(strlen(src) + 1);
    if(tmp)
        strcpy(tmp, src);
    return tmp;
}

void explode(const char *src, const char *tokens, char ***list, size_t *len)
{   
    if(src == NULL || list == NULL || len == NULL)
        return;

    char *str, *copy, **_list = NULL, **tmp;
    *list = NULL;
    *len  = 0;

    copy = strdup(src);
    if(copy == NULL)
        return;

    str = strtok(copy, tokens);
    if(str == NULL)
        goto free_and_exit;

    _list = realloc(NULL, sizeof *_list);
    if(_list == NULL)
        goto free_and_exit;

    _list[*len] = strdup(str);
    if(_list[*len] == NULL)
        goto free_and_exit;
    (*len)++;


    while((str = strtok(NULL, tokens)))
    {   
        tmp = realloc(_list, (sizeof *_list) * (*len + 1));
        if(tmp == NULL)
            goto free_and_exit;

        _list = tmp;

        _list[*len] = strdup(str);
        if(_list[*len] == NULL)
            goto free_and_exit;
        (*len)++;
    }


free_and_exit:
    *list = _list;
    free(copy);
}

then you have to call it:

char **list;
size_t i, len;
explode("this;is;a;string", ";", &list, &len);
for(i = 0; i < len; ++i)
    printf("%d: %s\n", i+1, list[i]);

/* free list */
for(i = 0; i < len; ++i)
    free(list[i]);
free(list);

this is an example running with valgrind:

valgrind ./a 
==18675== Memcheck, a memory error detector
==18675== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. 
==18675== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==18675== Command: ./a 
==18675== 
1: this
2: is
3: a
4: string
==18675== 
==18675== HEAP SUMMARY:
==18675==     in use at exit: 0 bytes in 0 blocks
==18675==   total heap usage: 9 allocs, 9 frees, 114 bytes allocated
==18675== 
==18675== All heap blocks were freed -- no leaks are possible
==18675== 
==18675== For counts of detected and suppressed errors, rerun with: -v
==18675== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

Generally this is what the strtok function is for:

char* tok;
tok = strtok(srcStr, "#");

while(tok != NULL)
{
    // Do stuff with tok
    tok = strtok(NULL, "#");
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!