2015-02-11 2 views
0

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

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

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

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

#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 ***? Когда я пытаюсь получить к нему доступ с &, хотя это, похоже, не нравится.

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

+4

'& result = ...' останавливаться прямо там. это не lvalue. – WhozCraig

+1

'& result' будет иметь тип' char **** 'внутри' split_string'. Вам нужно снять ссылку. Может быть, с '* result' вместо этого? –

ответ

3

Вы путаете разыменование с помощью адресации (что является полной противоположностью). Btw, я не мог найти 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 

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

Удачи.