Как выделить память для строк, введенных пользователем в режиме реального времени в C?

Мне нужно получить неизвестное количество строк от пользователя (через клавиатуру) и установить массив указателей строк, чтобы он указывал на все введенные строки.

Я определил переменную char tmp_strng[] для хранения строки, которую вводит пользователь, используя следующий код:

printf("Enter string number %d\n",num_of_strngs+1);
fflush(stdin);
scanf("%s",tmp_strng);

После этого я хотел бы выделить больше памяти для char *str_arr[], который является массивом, в котором будут храниться указатели на все строки. Сначала делаю выделение памяти с проверкой:

if((tmp_str_arr[num_of_strngs]=realloc(str_arr,strlen(tmp_strng)))==NULL)
        {
            free(str_arr);
            printf("Error: couldn't allocate memory. Exiting.");
            return 1;
        }
str_arr[num_of_strngs]=tmp_str_arr[num_of_strngs];
str_arr[num_of_strngs++]=tmp_strng;

Это на самом деле не работает ... может ли кто-нибудь сказать мне, что здесь не так (или правильно)? Я хотел бы максимально использовать realloc() и scanf() в качестве основных функций.


person user34920    schedule 06.03.2014    source источник
comment
fflush(stdin) — поведение undefined (хотя в некоторых реализациях оно может работать)   -  person Filipe Gonçalves    schedule 07.03.2014
comment
Этого кода недостаточно, чтобы понять ваш вопрос. Пожалуйста, покажите нам, что такое num_of_strngs, str_arr и tmp_str_arr.   -  person Filipe Gonçalves    schedule 07.03.2014
comment
Вы не можете перераспределить массив. Они фиксированы к размеру, который они объявили.   -  person TerraOrbis    schedule 07.03.2014
comment
num_of_strngs — это переменная типа int, которая содержит количество строк в str_arr[] (если хотите, длину массива). str_arr определяется как char *str_arr[];, а char *tmp_str_arr[]; - это просто временный массив, который я использую в случае сбоя выделения, если я не буду его использовать и выделение не удастся, я потеряю весь массив.   -  person user34920    schedule 07.03.2014
comment
@TerraOrbis - Могу ли я выделить память для массива размера x, а затем создать новый массив размера x+1 и использовать указатель, указывающий на массив размера x, чтобы указать на массив размера x+1?   -  person user34920    schedule 07.03.2014
comment
Да просто установите указатель на новый массив   -  person TerraOrbis    schedule 07.03.2014


Ответы (1)


Используйте функцию getline(), она автоматически malloc() выделит достаточно памяти для хранения строки. Использование выглядит следующим образом:

char* line = NULL;    //Setting this to NULL is important!
size_t bufferSize;
size_t characterCount = getline(&line, &bufferSize, stdin);
if(characterCount == (size_t)-1) {
    //error handling
} else {
    //do something with this line
    free(line);
}

Функция getline(), как и asprintf(), является частью стандарта POSIX-2008.

person cmaster - reinstate monica    schedule 06.03.2014
comment
getline возвращает ssize_t. Это важно, так как он может вернуть -1, и ваша проверка на ‹ 0 не имеет смысла для size_t. - person Ed S.; 07.03.2014