Копировать вложенные массивы массива строк с нулевым завершением

#arrays #c #string #null

#массивы #c #строка #null

Вопрос:

Предположим, у меня есть массив «массив строк»:

 {"hello", "I", "am", "C", NULL, "And", "I", "am", "C  ", NULL, "Now", "this", "is", "Java", NULL, NULL}
  

Как я могу извлечь NULL вложенные массивы с завершением из этого массива, чтобы я мог иметь следующее:

 char* arr1[] = {"hello", "I", "am", "C", NULL}
char* arr2[] = {"And", "I", "am", "C  ", NULL}
char* arr3[] = {"Now", "this", "is", "Java", NULL}
  

Сам этот массив передается в качестве аргумента функции, например, так:

 void function(char* strings[])
{
    int index = 0; 
    loop: 
    while(strings[index])
    {
        if(!strings[index   1]) break;
        // how can I add stuff to an array? 
          index;
    }
    if (strings[index] || strings[index   1]) goto loop;
    // Now what? 
}
  

РЕДАКТИРОВАТЬ: мне нужны фактические копии строк, возможно, с помощью strdup() .

РЕДАКТИРОВАТЬ 2: моя попытка добавлена, поскольку об этом просили (и я должен был предоставить это с самого начала). Кроме того, функции не нужно ничего возвращать: вся обработка выполняется внутри, а строки впоследствии отбрасываются (или сохраняются в другом месте), следовательно strdup() .

Комментарии:

1. Вы должны просто перебирать входной массив и завершать подмассив, когда находите значение NULL.

2. Следует ли копировать только указатели или вам нужно, чтобы сами строки также копировались?

3. Невозможно узнать, сколько массивов строк с нулевым завершением будет в результате. Возвращаемый тип function должен быть char*** вместо void .

4. OT: кажется, довольно плохая идея хранить подстроки в 3 разных массивах. Это означает, что функция не сможет обрабатывать входные данные с 4 или 5 или … или 100 подстроками. Используйте массив указателей на массивы указателей символов.

5. В любом случае — для этой задачи realloc ваш друг

Ответ №1:

У меня есть попытка:

 char*** group_strings(const char *strings[])
{
    uint index = 0;
    uint start_index = 0;
    uint num_groups = 0;
    uint *group_sizes = NULL;
    char ***grouped_strings = NULL;

    do
    {
        while (strings[index])
        {
            if (!index || !strings[index - 1]) start_index = index;
            if (!strings[index   1]) break;
              index;
        }

        group_sizes = !group_sizes ? (uint *) calloc(  num_groups, sizeof(int))
                                   : (uint *) realloc(group_sizes,   num_groups * sizeof(int));
        uint current_grp_size = index   1 - start_index;
        group_sizes[num_groups - 1] = current_grp_size;

        char **current_argument = (char **) calloc(current_grp_size, sizeof(char *));
        for (int i = 0; i < index   1 - start_index;   i)
        {
            current_argument[i] = strdup(strings[start_index   i]);
        }

        grouped_strings = !grouped_strings ? (char ***) calloc(1, sizeof(char **))
                                           : (char ***) realloc(grouped_strings, (num_groups - 1) * sizeof(char **));
        grouped_strings[num_groups - 1] = current_argument;

        index  = 2;
        if (!strings[index - 1] amp;amp; !strings[index]) break;
    } while (strings[index] || strings[index   1]);
    return grouped_strings;
}