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

时光怂恿深爱的人放手 提交于 2019-12-10 11:54:07

问题


Possible Duplicate:
Split string with delimiters in C

I'm searching a good way to "explode" a char* into other char* using a delimiter.

My delimiter will be #


回答1:


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)



回答2:


Generally this is what the strtok function is for:

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

while(tok != NULL)
{
    // Do stuff with tok
    tok = strtok(NULL, "#");
}


来源:https://stackoverflow.com/questions/12789883/parallel-to-phps-explode-in-c-split-char-into-char-using-delimiter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!