Intereting Posts

Создание массива для хранения массивов символов в 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] 

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

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

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

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

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

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

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

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

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

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


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

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

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

Тогда вы можете использовать его с fgets или что угодно.

 fgets(buf, BUFSZ, infile); 

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

 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 является указателем на символ. Но чтобы сохранить наше здравомыслие, мы пытаемся отвлечь часть этой отвлекающей детали на мгновение и рассматривать строки как отдельный тип данных.

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

 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. 

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

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

 char array[] = {"somestringhere"}; 

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

 char* array1[]; 

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

 char** array2[]; 

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

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

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

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

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

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

 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 */ 

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

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

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

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

 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);