Создание массива для хранения массивов символов в 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, чтобы указать.
Ответы
Ответ 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);