Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

Как создать динамический массив?

#c #массивы #динамические_массивы


Хочу разобраться с динамическим выделением памяти в c. Пришла в голову идея, попробовать
сделать программу, которая спрашивает у пользователя имя и записывает ввод в массив
типа char, но так чтобы массив сам выделял себе память. То есть без предварительного
выделения вида char name[30] = {0};. Я ввожу имя Магомед и массив сам выделяет себе
память на 7 символов. Как это сделать?
    


Ответы

Ответ 1



Я бы взял указатель, длину и зарезервированную длину. Примерно char * s = malloc(16); int size = 16; int used = 0; И дальше читаем по одному символу. Как только вносим его в s, тут же увеличиваем used; как только used == size, так сразу увеличиваем массив раза в два: s = realloc(s,size *= 2); И все. Мы всегда знаем, сколько места имеется, сколько занято. Как в векторе в C++.

Ответ 2



Вот есть функция, которая прочитывает указанный файл посимвольно, пока не встретит символ перевода строки или конец файла. Функция сама выделяет себе память, а после использования строки буфер надо освободить с помощью free. При нехватке памяти ввод обрывается и возвращаются считанные символы или NULL, если не удалось ничего получить. Кроме того, для удобства чтения стандартного ввода предлагается макрос. char* get_full_line(FILE* f) { size_t capacity = 16; // начальный объем массива char* str = malloc(capacity); size_t length = 0; if (!str) return NULL; int ch; while ((ch = fgetc(f)) != '\n' && ch != EOF) { if (length >= capacity) { char* p = realloc(str, capacity *= 4); // коэфициент прироста if (!p) break; str = p; } str[length++] = ch; } str[length] = '\0'; return str; } #define read_full_line() ( get_full_line(stdin) )

Ответ 3



А вот ещё подготовил пример приветствия. Используется функция getline(3) из расширения библиотеки языка си. int main() { printf("Ваше имя: "); char* name = NULL; size_t capacity = 0; ssize_t length = getline(&name, &capacity, stdin); if (length > 0 && name[length - 1] == '\n') { name[length - 1] = '\0'; // убирает перевод строки } printf("Привет, %s!\n", name ?: "незнакомец"); free(name); return 0; } Кроме того, в этом кусочке кода встречается ещё одно расширение GNU — тренарный оператор без второго операнда. В этом случае, если первый операнд не равен нулю, он будет взят в качестве результата, иначе берётся третий операнд.

Комментариев нет:

Отправить комментарий