Как мне создать функцию в C, которая позволяет мне разбивать строку на основе разделителя в массив?

Я хочу создать функцию в C, чтобы я мог передать функции строку и разделитель, и он вернет мне массив с разделенными частями строки на основе разделителя. Обычно используется для разделения предложения на слова.

например: "hello world foo" -> ["hello", "world", "foo"]

Тем не менее, я новичок в C, и многие указатели меня смущают. Я получил ответ главным образом на этот вопрос, но он встроен, поэтому, когда я пытаюсь разделить его на функцию, логика указателей вводит меня в заблуждение:

Это то, что я до сих пор:

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

void split_string(char string[], char *delimiter, char ***result) {
    char *p = strtok(string, delimiter);
    int i, num_spaces = 0;

    while (p != NULL) {
        num_spaces++;
        &result = realloc(&result, sizeof(char *) * num_spaces);

        if (&result == NULL) {
            printf("Memory reallocation failed.");
            exit(-1);
        }

        &result[num_spaces - 1] = p;

        p = strtok(NULL, " ");
    }

    // Add the null pointer to the end of our array
    &result = realloc(split_array, sizeof(char *) * num_spaces + 1);
    &result[num_spaces] = 0;

    for (i = 0; i < num_spaces; i++) {
        printf("%s\n", &result[i]);
    }

    free(&result);
} 

int main(int argc, char *argv[]) {
    char str[] = "hello world 1 foo";
    char **split_array = NULL;

    split_string(str, " ", &split_array);

    return 0;
}

Суть в том, что у меня есть функция, которая принимает строку, принимает разделитель и принимает указатель, где сохранить результат. Затем он строит результат. Переменная для результата начинается с NULL и без памяти, но я постепенно перераспределяю память для нее по мере необходимости.

Но я действительно запутался в отношении указателей, как я уже сказал. Я знаю, что мой результат имеет тип char ** как строка это типа char * и их много, так что вам нужны указатели для каждого, но тогда я должен передать местоположение этого char ** к новой функции, верно, поэтому она становится char ***? Когда я пытаюсь получить к нему доступ с & хотя, похоже, это не нравится.

Я чувствую, что мне здесь не хватает чего-то фундаментального, и я действительно ценю понимание того, что не так с кодом.

1 ответ

Решение

Вы путаете разыменование с адресацией (что является полной противоположностью). Кстати, я не мог найти split_array где-нибудь в функции, как это было в main, Даже если бы у вас была правильная разыменование и адресация, у этого все равно были бы другие проблемы.

Я уверен, что вы пытаетесь сделать это:

#include <stdio.h>
#include <stdlib.h>

void split_string(char string[], const char *delimiter, char ***result)
{
    char *p = strtok(string, delimiter);
    void *tmp = NULL;
    int count=0;

    *result = NULL;

    while (p != NULL)
    {
        tmp = realloc(*result, (count+1)*sizeof **result);
        if (tmp)
        {
            *result = tmp;
            (*result)[count++] = p;
        }
        else
        {   // failed to expand
            perror("Failed to expand result array");
            exit(EXIT_FAILURE);
        }

        p = strtok(NULL, delimiter);
    }

    // add null pointer
    tmp = realloc(*result, (count+1)*sizeof(**result));
    if (tmp)
    {
        *result = tmp;
        (*result)[count] = NULL;
    }
    else
    {
        perror("Failed to expand result array");
        exit(EXIT_FAILURE);
    }
}

int main()
{
    char str[] = "hello world 1 foo", **toks = NULL;
    char **it;

    split_string(str, " ", &toks);

    for (it = toks; *it; ++it)
        printf("%s\n", *it);
    free(toks);
}

Выход

hello
world
1
foo

Честно говоря, это было бы чище, если бы использовался результат функции, а не параметр in/out, но вы выбираете последний, так что все готово.

Удачи.

Другие вопросы по тегам