Как мне хранить несколько массивов строк во время выполнения, в C? - PullRequest
0 голосов
/ 15 октября 2018

Я создал несколько массивов строк во время выполнения и знаю количество массивов, которые необходимо сохранить.

Я хочу сохранить их или указать на них.Я не уверен, как это сделать или насчет синтаксиса и не могу найти учебники.Я полагаю, что это можно сделать с помощью struct или char ** []?

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

  struct arrayholder{
   const char **argv;
  };

  char *str_arr1[] = { "sdfddsf", "foo1", 0 };
  char *str_arr2[] = { "sdsosdfrt", "foo2", 0 };
  char *str_arr3[] = { "grsdsfdep", "foo3", 0 };


  struct arrayholder the_arrays [] = { {str_arr1},{str_arr2},{str_arr3} };

//      The contents should look like,
//         the_arrays[0] ==> {str_arr1}
//         the_arrays[0].argv[0] ==> "sdfddsf"
//         the_arrays[0].argv[1] ==> "foo1"

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

В точке, где вы знаете количество массивов, вы можете создать двумерный массив char*.Или, что более удобно, указатель на первый элемент такого массива.Первый элемент будет массивом типа char* [n], поэтому указатель на него будет иметь тип char* (*)[n].Пример:

char* (*str_table)[y] = malloc(sizeof (char*[x][y]));

Затем заполните этот 2D-массив, вызывая malloc для каждого элемента.Пример:

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

static char* random_string (void)
{
  static char str[10+1];
  size_t size = rand()%10 + 1;
  size_t i;

  for(i=0; i<size; i++)
  {
    str[i] = rand() % ('Z' - 'A' + 1) + 'A';
  }
  str[i] = '\0';
  return str;
}

int main (void)
{
  srand(time(NULL));

  size_t x = 3;
  size_t y = 2;

  char* (*str_table)[y] = malloc(sizeof (char*[x][y]));
  assert(str_table);

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      char* str = random_string();
      size_t str_size = strlen(str)+1;
      str_table[i][j] = malloc(str_size);
      assert(str_table[i][j]);
      strcpy(str_table[i][j], str);

      printf("%s ", str_table[i][j]);
    }
    printf("\n");
  }


  free(str_table);
}

Это печатает 3 строки с 2 случайными строками на строку.

0 голосов
/ 15 октября 2018

Вы, как программист, должны решить, как вы будете хранить данные.У вас есть несколько опций, имейте в виду, что:

  1. 'строка' - это хранимые символы массива, оканчивающиеся нулевым байтом, т.е.'\0'
  2. Вам необходимо сохранить количество элементов массива в массиве.
  3. В случае «строк» ​​количество элементов в массиве / количество символов в строкеможет быть вычислено путем подсчета количества символов, пока не встретится нулевой байт '\ 0'.
  4. Для всех других массивов у вас есть два варианта.
    1. Вы явно устанавливаете последний член массива на NULL / ноль, как вы это делали в случае str_arr1[] = { "sdfddsf", "foo1", 0 };.При копировании такого массива вам нужно помнить, чтобы явно установить последний элемент на ноль.В этом случае вы часто будете видеть магический код + 1 при расчете размера, например malloc(sizeof(char) * (strlen(string) + 1)).
    2. Размер массива можно хранить в отдельной переменной, обычно типа size_t.
  5. У вас есть 3 массива строк, т.е.три массива, оканчивающиеся на NULL массива, оканчивающиеся нулевым байтом символов.
  6. Вы хотите иметь массив массивов строк.Вам нужно решить, как вы будете отслеживать размер этого массива и размер внутренних массивов.
  7. Мне не нравится иметь явное значение завершения массива.Мне нравится хранить размеры массива, используя отдельную переменную типа size_t.Обычно я оборачиваю указатель на массив и переменную, которая хранит размер в одной структуре.Таким образом, я могу написать отдельные библиотеки для каждого уровня массива.
  8. Пожалуйста, не выбирайте char ***var;.Код становится нечитаемым
0 голосов
/ 15 октября 2018

Вы можете использовать 3D-массив, как в этом случае: C 3D-массив символов .

Или вы можете использовать простой связанный список, где каждый узел является 2D-массивом..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...