Массивы символов в структуре - PullRequest
0 голосов
/ 08 февраля 2011

Если кто-то хочет добавить массив char* (строка) в структуру, как выглядит синтаксис?

например,

struct someStruct
{
     char **someStrings;
}

Где можно установить ограничение длинынапример, установить для каждого члена someString ограничение в десять символов?

Ответы [ 3 ]

2 голосов
/ 08 февраля 2011

Если вы заранее знаете, сколько строк вам понадобится (назовите это M) и максимальную длину для каждой строки (назовите это N), тогда вы просто объявите двумерный массив char:

#define M ... // number of strings
#define N ... // max length of each string

struct someStruct
{
  char someStrings[M][N+1];  // +1 for 0 terminator
  ...
};

Если вы не знаете, сколько строк вам понадобится, но знаете максимальную длину, вы можете объявить указатель на массив символов:

#define N ...

struct someStruct
{
  char (*someStrings)[N+1];
  size_t numStrings;
  ...
};

Затем, когда вам нужночтобы выделить массив строк, вы должны сделать что-то вроде:

struct someStruct s = {NULL, 0};
size_t count = getNumStrings();
s.someStrings = malloc(sizeof *s.someStrings * count);
if (s.someStrings)
  s.numStrings = count;

И теперь вы можете обрабатывать someStrings как массив строк:

strcpy(s.someStrings[i], "foo");
printf("%s\n", s.someStrings[j]);
s.someStrings[i][j] = 'a';

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

free(s.someStrings);

ПРИМЕЧАНИЕ : при работе с указателями на массивы вы должны разыменовывать указатель перед применением индекса;учитывая код

T (*a)[N];
a = malloc(sizeof *a); // allocates a single N-element array of T

, вам обычно нужно написать (*a)[i] для правильного доступа к i-му элементу массива (*a[i] анализируется как *(a[i]), что здесь не так),Помните, однако, что a[0] эквивалентно *a;применение индекса к a неявно разыменовывает его, поэтому a[0][i] эквивалентно (*a)[i].Если бы мы выделяли его как

a = malloc(sizeof *a * M); // allocates M N-element arrays of T

, то мы могли бы ссылаться на каждый массив как a[0], a[1] и т. Д., А каждый элемент каждого массива - как a[0][0], a[0][1] и т. Д.почему вы не видите указателя гимнастики в коде выше.

Если вы не знаете, сколько строк или максимальная длина каждой строки, вам придется выполнить двухэтапное распределение, например так:

struct someStruct
{
  char **someStrings;
  size_t numStrings;  
  size_t maxLength;
};

struct someStruct s = {NULL, 0, 0};
size_t count = getNumStrings();
s.maxLength = getMaxLength();
s.someStrings = malloc(sizeof *s.someStrings * count); 
if (s.someStrings)
{
  size_t i;
  s.numStrings = count;
  for (i = 0; i < s.numStrings; i++)
  {
    s.someStrings[i] = malloc(sizeof *s.someStrings[i] * s.maxLength + 1);
    if (s.someStrings[i])
      // initialize string value here
  }
}

Опять выможет обрабатывать someStrings как обычный двумерный массив:

strcpy(s.someStrings[i], "foo");
printf("%s", s.someStrings[j]);
s.someStrings[i][j] = 'a';

Подобно выделению, освобождение происходит в два этапа:

for (i = 0; i < s.numStrings; i++)
  free(s.someStrings[i]);
free(s.someStrings);

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

Вы должны будете отслеживать количество строк и максимальную длину каждой строки вручную;нет способа получить эту информацию из одних только значений указателя.

1 голос
/ 08 февраля 2011
#define NUM_STRINGS 5 // for example
#define STRING_LENGTH 11 // for example

struct someStruct
{
    char stringArray[NUM_STRINGS][STRING_LENGTH];
}

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

0 голосов
/ 08 февраля 2011

char ** - это массив строк.Простая строка: char *.

Если вы хотите ограничить ее длину, вы можете использовать char someString[11].(+1 для включения нулевого символа в конце).

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