2011-02-08 3 views
0

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

например.

struct someStruct 
{ 
    char **someStrings; 
} 

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

+0

Вы хотите ограничить someString, чтобы удерживать десять строк или каждую строку, чтобы удерживать десять символов? – mkb

+0

каждая строка, чтобы удерживать десять символов – jarryd

+0

Я не думаю, что вы действительно можете сделать это на C, а не автоматически. Размер массива не является частью его типа (например, в Go). – mkb

ответ

2

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

#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; 
    ... 
}; 

Затем, когда вам нужно Распределяйте string array, вы бы сделали что-то вроде:

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, как обычный 2D массив:

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

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

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

+0

Это было действительно полезно;) – jarryd

0

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

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

+0

Я хочу массив строк и ограничиваю каждую строку, например. 10 символов? – jarryd

1
#define NUM_STRINGS 5 // for example 
#define STRING_LENGTH 11 // for example 

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

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

Смежные вопросы