Страницы

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

пятница, 13 декабря 2019 г.

Динамическое выделение памяти с помощью scanf

#c #массивы #память #strlen


Как с помощью scanf выделить память и занести в переменную.

Предположим, что пользователь вводит очень длинный текст и заранее определенный размер
массива обрезает строку. Пробовал не указывать размер массива и присваивать пустую
строку (""), но strlen всегда возвращает 0, а если присутствуют символы в str, то длину
строки.

Где проблема?

char str[] = "";
scanf("%s",str);
printf ("Line size \"%s\" - %d characters\n", str, strlen (str) );

    


Ответы

Ответ 1



Объявление char str[] = ""; эквивалентно объявлению char str[1] = ""; Массив получает размер 1, который после этого уже больше никогда не поменяется. В такой массив невозможно поместить никакую строку, кроме пустой. В любом случае, локальный или статический массив в языке С получает конкретный фиксированный размер в точке определения. Поменять этот размер позже уже невозможно. Поэтому решить задачу чтения строки неизвестной длины с использованием явного объявления массива не получится. Размер массива придется менять по мере необходимости, т.е. "на лету". А изменяться "на лету" может только размер динамически выделенного (через malloc) массива. Однако даже в этом случае какого-либо готового решения в стандартном scanf нет. Для чтения строк неизвестной, заранее неограниченной длины лучше использовать не scanf, а циклический вызов fgets с периодическим realloc-ом динамического буфера, пока не прочитана вся строка. Тем не менее, GNU scanf поддерживает нестандартный модификатор m, реализующий требуемую функциональность. Этот модификатор работает с форматами s и []: char *str = NULL; scanf("%ms", &str); ... free(str); Обратите внимание, что передавать в scanf в этом случае следует указатель на указатель, т.е. аргумент типа char **. Ранее в этой роли выступал модификатор a. Однако начиная с C99 символ a "занят" под один из стандартных форматов. Поэтому если вы захотите воспользоваться этой возможностью, будьте внимательны с версией библиотеки.

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

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