2013-05-17 3 views

ответ

0

malloc является одним из способов:

char* const string = (char*)malloc( NCharacters ); // allocate it 
...use string... 
free(string); // free it 

где NCharacters это количество символов, которые необходимо в этом массиве.

0

Если вы пишете код самостоятельно, ответ будет включать malloc() и realloc(), а может быть strdup(). Вам нужно будет прочитать строки (строки) в массив больших символов, а затем скопировать строки (с strdup()) в массив указателей символов с динамическим размером.

char line[4096]; 
char **strings = 0; 
size_t num_strings = 0; 
size_t max_strings = 0; 

while (fgets(line, sizeof(line), stdin) != 0) 
{ 
    if (num_strings >= max_strings) 
    { 
     size_t new_number = 2 * (max_strings + 1); 
     char **new_strings = realloc(strings, new_number * sizeof(char *)); 
     if (new_strings == 0) 
      ...memory allocation failed...handle error... 
     strings = new_strings; 
     max_strings = new_number; 
    } 
    strings[num_strings++] = strdup(line); 
} 

После этого цикла, есть достаточно места для max_strings, но только num_strings используются. Вы можете проверить, что strdup() удалось, и там также обрабатывает ошибку выделения памяти, или вы можете подождать, пока не попытаетесь получить доступ к значениям в массиве, чтобы обнаружить эту проблему. Этот код использует тот факт, что realloc() выделяет память заново, когда «старый» указатель имеет значение NULL. Если вы предпочитаете использовать malloc() для первоначального распределения, вы могли бы использовать:

size_t num_strings = 0; 
size_t max_strings = 2; 
char **strings = malloc(max_strings * sizeof(char *)); 

if (strings == 0) 
    ...handle out of memory condition... 

Если вы не strdup() автоматически, достаточно просто написать свой собственный:

char *strdup(const char *str) 
{ 
    size_t length = strlen(str) + 1; 
    char *target = malloc(length); 
    if (target != 0) 
     memmove(target, str, length); 
    return target; 
} 

Если вы работающий в системе с поддержкой POSIX getline(), вы можете просто использовать, что:

char *buffer = 0; 
size_t buflen = 0; 
ssize_t length; 
while ((length = getline(&buffer, &buflen, stdin)) != -1) // Not EOF! 
{ 
    …use string in buffer, which still has the newline… 
} 
free(buffer); // Avoid leaks 
+0

memmove()? Вероятно, это сработает, но я думаю, что вы имели в виду memcpy(). – wildplasser

+0

@wildplasser: Нет, я имел в виду 'memmove()'. В этом контексте 'memcpy()' также будет работать, но 'memcpy()' не всегда работает, и 'memmove()' всегда работает, поэтому я всегда использую 'memmove()', потому что он абсолютно надежный, тетср() '. –

+1

Это может не нанести вреда, но это может смутить новых. NTW: Мне не нравится, что «цель» тоже является числовой постоянной нуля. Я бы предпочел: 'if (target) memcpy (target, str, length);' – wildplasser

-1

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

while ((ch == getchar()) != '$') 
{ 
    scanf("%c", &ch); 
} 
+0

Существует так много проблем с этим фрагментом, это страшно. Вы сравниваете результат 'getchar()' с 'ch', а не присваиваете. Результатом сравнения будет 0 или 1, ни один из которых не совпадает с '' $ ''в любом стандартном наборе кодов, поэтому цикл продолжается навсегда. Если 'ch' имеет тип' char', 'scanf()' считывает другой символ (без проверки); если 'ch' имеет тип' int' (как и для получения результата 'getchar()'), тогда вызов 'scanf()' пропускает неправильный тип указателя (хотя вы можете не заметить проблему на мини-машинах). Все это создает проблемы. –

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