Динамическое заполнение массива c с клавиатуры [C] - PullRequest
0 голосов
/ 02 февраля 2020

Я реализовал динамическую c структуру данных массива в C; и теперь я ищу правильный способ заполнить мои массивы от stdin. Использование scanf() или fgets() кажется не очень хорошей идеей, так как размер их буфера фиксирован во время компиляции, я бы потерял динамичность своей структуры. Поэтому я использую getline() и выделяю память динамически для каждого символа, который я хочу поместить в свой массив.

Я написал эту функцию для заполнения двух массивов из stdin:

//input arrays from keyboard
void use_input_array(){
 char *line = NULL;
 size_t len = 0;
 ssize_t read;
 puts("Enter your first ARRAY : ");

 struct dynarray *first;
 create_dynarray(&first, 1);

 while((read = getline(&line, &len, stdin)) != -1){
   if(read > 0){
    add_elem(first, line);
   }
 }
 free(line);

 char *sline = NULL;
 size_t slen = 0;
 ssize_t sread;
 puts("Enter your second ARRAY :");

 struct dynarray *second;
 create_dynarray(&second, 1);

 while((sread = getline(&sline, &slen, stdin)) != -1){
   if(sread > 0){
     add_elem(second, sline);

   }
 free(sline);    
 }
 puts("END");
}

Когда я выполняю функцию, я могу вставлять первую строку без проблем, но когда дело доходит до второй, выполнение идет непосредственно до конца. Я понятия не имею, почему это происходит. Вот небольшой компилируемый пример, чтобы лучше показать мою проблему:

#include<stdio.h>
#include<stdlib.h>

typedef struct dynarray
{
   void **memory;
   size_t allocated;
   size_t used;
   int index;
} dynarray;


void create_dynarray(dynarray **array, size_t size)
{
  *array = calloc(size, sizeof **array);
  (*array)->memory = NULL;
  (*array)->allocated = 0;
  (*array)->used = 0;
  (*array)->index = -1;
}



//adds a new element at the bottom of dynarray
void add_elem(dynarray *array, void *data)
{
  size_t toallocate;
  size_t size = sizeof(void *);
  if ((array->allocated - array->used) < size){
    toallocate = array->allocated == 0 ? size : (array->allocated * 2);
    array->memory = realloc(array->memory, toallocate);
    array->allocated = toallocate;
  }

  array->memory[++array->index] = data;
  array->used = array->used + size;
}

//input arrays from keyboard
void use_input_array(){
  char *line = NULL;
  size_t len = 0;
  ssize_t read;
  puts("Enter your first ARRAY : ");

  struct dynarray *first;
  create_dynarray(&first, 1);

  while((read = getline(&line, &len, stdin)) != -1){
    if(read > 0){
     add_elem(first, line);
    }
  }
  free(line);

  char *sline = NULL;
  size_t slen = 0;
  ssize_t sread;
  puts("Enter your second ARRAY :");

  struct dynarray *second;
  create_dynarray(&second, 1);

  while((sread = getline(&sline, &slen, stdin)) != -1){
    if(sread > 0){
      add_elem(second, sline);

    }
  free(sline);    
  }
  puts("END");
}

int main(){

  use_input_array();
}


Другая проблема связана с тем фактом, что моя входная строка представляет собой массив char, но моя структура построена так, что она не содержит типов, поэтому она ожидает пустой указатель Я мог бы создать массив int, double et c. выполнить преобразование, но это также означало бы иметь фиксированный размер. Я думал о реализации своей собственной функции покрытия и вызове ее перед вставкой элемента в массив. Но я действительно не знаю с чего начать ... Есть предложения? Спасибо.

1 Ответ

2 голосов
/ 02 февраля 2020

Примерно так может работать.
Для getline нужен только один указатель. Поскольку указатель назначен array->memory[++array->index] = data;, для каждой итерации должно быть выделено больше памяти. Установите line в NULL и len в ноль.
Рассмотрите возможность выхода из l oop при вводе пустой строки. '\n' == line[0].
Бесплатно line в самом конце.

char *line = NULL;
size_t len = 0;
ssize_t read;
puts("Enter your first ARRAY : ");

struct dynarray *first;
create_dynarray(&first, 1);

while((read = getline(&line, &len, stdin)) != -1){
    if ( '\n' == line[0]) {
        break;
    }
    if(read > 0){
        add_elem(first, line);
        line = NULL;
        len = 0;
    }
}

puts("Enter your second ARRAY :");

struct dynarray *second;
create_dynarray(&second, 1);

while((read = getline(&line, &len, stdin)) != -1){
    if ( '\n' == line[0]) {
        break;
    }
    if(read > 0){
        add_elem(second, line);
        line = NULL;
        len = 0;

    }
}
free(line);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...