2

重複の可能性:
Cで区切り文字を使用して文字列を分割する

区切り文字を使用して、char*を他のchar*に「分解」するための良い方法を探しています。

私の区切り文字は#

4

2 に答える 2

11

strtokCrazyCastaが言ったように使用できますが、彼/彼女のコードは間違っています。

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);

strtokソースポインタを使用して最初に呼び出す必要があり、その後はを使用する必要があることに注意してくださいNULL。また、見つかった文字列を終了するために書き込むsrcため、書き込み可能である必要があります。したがって、文字列の読み取り方法(および後で使用するかどうか)に応じて、文字列のコピーを作成する必要があります。しかし、私が言ったように、これは必ずしも必要ではありません。strtok\0

編集:

関数は次のexplodeようになります。

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);
}

次に、それを呼び出す必要があります:

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);

これは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)
于 2012-10-08T21:55:05.863 に答える
1

一般的に、これはstrtok関数の目的です。

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

while(tok != NULL)
{
    // Do stuff with tok
    tok = strtok(NULL, "#");
}
于 2012-10-08T21:44:38.100 に答える