Подтвердить что ты не робот

Создание массива для хранения массивов символов в C

В настоящее время мой C немного более чем ржавый, поэтому я не могу создать что-то, что, по-моему, должно быть довольно простым.

Позвольте мне ссылаться на массивы символов как строки для этого сообщения. Это сделает вещи более ясными как для меня, так и для вас.

У меня есть массив, который может содержать 1 или более строк. Например { "ab", "cd", "ef" }. Я хочу сделать другой массив для хранения нескольких версий массива строк. Так что что-то вроде {{ "ab", "cd", "ef" }, { "gh", "ij" }, { "kl" }}.

То, что у меня есть сейчас:

char *arrayOfStrings[50]; // a single array to hold multiple strings
char **arrayOfArraysOfStrings[10]; // array to hold multiple snapshots of arrayOfStrings

Массив строк изменяется со временем, и я использую массив массивов строк, чтобы в основном хранить исторические снимки arrayOfStrings. Моя проблема возникает, когда мне нужно получить доступ к массиву моментальных снимков для данных. Это код, который я должен помещать в массив моментальных снимков:

arrayOfArraysOfStrings[input_index] = arrayOfStrings; // you can assume input_index is updated correctly, I've already checked that.

Это кажется неправильным, поскольку, когда я пытаюсь получить доступ и распечатать содержимое массива моментальных снимков, он только распечатывает информацию из самых последних arrayOfStrings. Идея, с которой я шел, заключалась в том, чтобы сохранить адрес, где arrayOfChars указывает на запись массива моментальных снимков, чтобы я мог получить к нему доступ позже.

В настоящий момент доступ к записи в массиве моментальных снимков выполняется следующим образом:

arrayOfArraysOfChars[historicalIndex][indexOfTargetChar]

Есть несколько вопросов, на которые я хочу ответить:

  • Я полагаю, что метод, который я изложил, подходит для того, что я пытаюсь сделать, или есть недостаток в моей общей логике?
  • Что я делаю неправильно с моим текущим кодом и как его исправить?
  • Есть ли лучший способ сделать это, и если да, то как работает инициализация массивов, добавление массивов и чтение из массивов?

- редактировать 4/18-- Отчасти проблема заключается в том, что я устанавливаю указатели в arrayOfArraysOfStrings, чтобы указать на то же, что указывает на arrayOfStrings. Это плохо, поскольку arrayOfStrings редактируется. Мне нужно каким-то образом дублировать 2D-массив... Предпочтительно, просто выделив новый блок памяти для arrayOfStrings, чтобы указать.

4b9b3361

Ответ 1

У вас есть одно слишком много указателей в обоих ваших массивах.

char arrayOfChars[50]; // a single array of characters
char *arrayOfArraysOfChars[10]; // array to hold multiple single arrays of characters

Поскольку arrayOfChars используется как буфер (новые данные всегда идут туда первым), вам нужно сохранить копию строки в arrayOfArrays. Здесь должна помочь функция POSIX strdup.

Примечание & и * являются противоположностями, поэтому &* и *& ничего не делают.

Вы также можете сделать arrayOfArrays буквально этим.

char arrayOfChars[50]; // a single array of characters
char arrayOfArraysOfChars[10][50]; // array to hold multiple single arrays of characters

С помощью этой настройки вы должны использовать strcpy для копирования данных в arrayOfArrays.


Прочитав ваше редактирование, я думаю, вам нужно начать очень просто. И FWIW имена переменных - неправильный вид венгерского.

Для того, что я думаю, что вы пытаетесь сделать, я бы начал с всего лишь одного массива char. Это будет основной буфер, чтобы удерживать строки, которые вводятся и просматриваются.

enum { BUFSZ = 50 };
char buf[BUFSZ + 1];

Затем вы можете использовать его с fgets или любым другим.

fgets(buf, BUFSZ, infile);

Чтобы сохранить их в массиве, я бы использовал strdup для автоматической обрезки. Если строки будут состоять в основном из двух символов, я не хочу использовать 48 дополнительных байтов для каждого из них. Итак, массив указателей char (строки).

enum { STRVSZ = 40 };
char *strv[STRVSZ + 1];
int i;
i = 0;
strv[i] = strdup(buf);
strv[i+1] = NULL; // This makes it an "argv-style" NULL-terminated array of strings
++i; // i is now the index of the next element, and a count of elements already added

Каждый элемент strv является указателем char. Но чтобы сохранить наше здравомыслие, мы пытаемся отвлечь часть этой отвлекающей детали на мгновение и рассматривать строки как отдельный тип данных.

Теперь, чтобы создать списки из них, мы делаем то же самое снова. Но нет функции strdup -type для создания дубликата массива указателей, поэтому нам нужно отделить выделение и копирование.

enum { STRVVSZ = 20 };
char **strvv[STRVVSZ + 1];
int j;
j = 0;
strvv[j] = calloc(i+1, sizeof *strvv[j]); // assuming i is the count of elements 
memcpy(strvv[j], strv, i * sizeof *strvv[j]);
++j; // j is now the index of the next string-pointer array in the array-of-same,
     // and a count of elements already added.

Теперь мои имена так же глупы, как ваши, но они короче!

Ответ 2

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

char array[] = {"somestringhere"};

теперь вы хотите сохранить такие массивы в другом массиве. это просто:

char* array1[];

массив 1 будет хранить значения, которые имеют тип char* типа i.e адрес массивов символов. теперь вы хотите сохранить их в другом массиве,

char** array2[];

это массив [адрес массивов] теперь все, что вам нужно сделать, это:

array1[0] = array; //same as: array1[0] = *array[0];
array2[0] = *array1[0];

Теперь у вас есть все, что вам нужно. Надеюсь, вы поняли, к сути.:)

Ответ 3

Этот пример был выполнен с использованием turbo c + 1.01 dos и работает также в версии 3.0 dos.

char * text[] = {
  "message1",
  "message2",
  "message3"
};

Ответ 4

Обратите внимание, что в ваших примерах показаны массивы указателей. Если вы хотите, чтобы массивы массивов (многомерные массивы) задавали все размеры в определении массива.

char sentences[500][42]; /* sentences is an array of 500 elements.
                         ** each element is itself an array
                         ** capable of holding strings up to length 41 */

Ответ 5

если хранить текст в файле .c или .h, имеющем более одной строки текста, эквивалентно к идее массива массивов char. может сделать это:

char * text[] = {
  "message1",
  "message2",
  "message3"
};

также может использовать char * текст [], char рядом * текст [], char far * text [], char огромный * текст []. должен иметь символ звездочки или звезды для указателя.

a для цикла может использоваться для отображения текста:

char i; // int type can also be used
for (i = 0, i < 3; i++)
  printf("%s\n", text[i]);

другие циклы:

char i = 0;  // may not be zero when declared as "char i;" only
while (i < 3) {
  printf("%s\n", text[i]);
  i++;
 }

или

char i = 0;  // may not be zero when declared as "char i;" only
do {
 printf("%s\n", text[i]);
 i++;
} while (i < 3);