У вас есть две проблемы, что каждая из них должна быть решена отдельно, но они все еще могут быть решены в похожи способом, а именно с использованием динамического распределения памяти и, что более важно перераспределению ,
Здесь есть два важных аспекта, и первое состоит в том, что строка представляет собой массив символов (со специальным завершающим символом) и что вы можете иметь указатель на массив, расположенный в любом месте в памяти.
Если мы начнем с типов данных и как вы должны хранить свои строки, то вы хотите, чтобы массив массивов, как и сейчас, но динамически распределялся, что означает, что вам нужен массив указателей (к строки), но поскольку массив строки также должен быть динамическим, вам нужен указатель на массив, содержащий указатели на другие массивы, то есть указатель на указатель на char
: char **
.
Теперь, когда мы знаем, какой тип данных использовать, подумайте о том, как его выделить. Для того, чтобы выделить место для одной строки в массиве, вы выделяете один char *
с помощью функции malloc
:
char **strings = malloc(1 * sizeof(char *));
Это была простая часть. Теперь, прежде чем мы начнем чтение фактической строки, позволяет думать о том, как добавить новую строку в коллекцию: Это делается перераспределение массива строк, которые вы имеете, используя realloc
функцию:
char **temp_strings = realloc(strings, current_count + 1 * sizeof(char *));
if (temp_string == NULL)
{
// Allocation failed, handle error appropriately
}
strings = temp_strings;
++current_count;
Здесь переменная current_count
- это текущая длина массива строк, она должна быть первоначально инициализирована до 1
(так как у нас только одна строка в массиве).
Теперь для чтения фактических строк, и это немного сложнее, поскольку мы на самом деле не можем читать целые строки (так как мы не знаем, как долго каждая строка). Вместо этого мы читаем по одному персонажу за раз и заканчиваем, когда попадаем в новую строку. Нам также нужно перераспределить строку для каждого символа.
Может быть что-то вроде этого:
int ch;
char *s = NULL;
size_t current_length = 0; // Current length of string
while ((c = fgetc(stdin)) != EOF)
{
if (c == '\n')
break; // Newline, done with the current string
if (s == NULL)
{
s = malloc(2); // Allocate two character: One for c and one for the terminator
}
else
{
// The current length is not including the terminator
// that's why we add two characters
char *temp_s = realloc(s, current_length + 2);
if (temp_s == NULL)
{
// Handle error
}
s = temp_s;
}
s[current_length++] = c;
s[current_length] = '\0'; // Terminate as a string
}
if (s != NULL)
{
// "Add" the string to the array of strings
strings[current_count] = s;
}
Нет, это может занять 10 слов с 8 символов каждый (плюс строка терминатор). –
Вам нужно будет сохранить строки в качестве указателей на символы в динамически распределенном массиве. Затем вы можете отсортировать элементы 'char *' в массиве. Таким образом, строки и массив могут иметь любую длину. – Baldrick
благодарит за отзыв, как бы вы предложили мне это сделать? Я только программировал C со статическими значениями до, а не произвольной длины. – Joel