来自键盘输入的动态数组填充[C]

来自键盘输入的动态数组填充[C],c,data-structures,dynamic-arrays,keyboard-input,C,Data Structures,Dynamic Arrays,Keyboard Input,我用C实现了一个动态数组数据结构;我现在正在寻找一种合适的方法来填充stdin中的数组。使用scanf()或fgets()似乎不是一个好主意,因为它们的缓冲区大小在编译时是固定的,我将失去结构的动态性。因此,我使用getline()并为我要放入数组中的每个字符动态分配内存 我编写此函数是为了填充stdin中的两个数组: //input arrays from keyboard void use_input_array(){ char *line = NULL; size_t len = 0;

我用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();
}


#包括
#包括
typedef结构dynarray
{
空虚**记忆;
分配的大小;
使用的尺寸;
整数指数;
}dynarray;
无效创建动态数组(动态数组**数组,大小\u t大小)
{
*array=calloc(大小、大小**数组);
(*数组)->memory=NULL;
(*数组)->已分配=0;
(*数组)->used=0;
(*数组)->index=-1;
}
//在dynarray底部添加新元素
void add_elem(dynarray*数组,void*数据)
{
要分配的大小;
大小=大小(空*);
如果((数组->已分配-数组->已使用)已分配==0?大小:(数组->已分配*2);
数组->内存=realloc(数组->内存,待分配);
数组->分配=分配;
}
数组->内存[++数组->索引]=数据;
数组->使用=数组->使用+大小;
}
//从键盘输入数组
无效使用\u输入\u数组(){
char*line=NULL;
尺寸长度=0;
阅读;
放置(“输入您的第一个数组:”);
结构dynarray*第一;
创建_dynarray(&first,1);
while((read=getline(&line,&len,stdin))!=-1){
如果(读取>0){
添加元素(第一行);
}
}
自由线;
char*sline=NULL;
尺寸=0;
塞泽斯雷德;
放置(“输入第二个数组:”);
结构dynarray*second;
创建_dynarray(&second,1);
while((sread=getline(&sline,&slen,stdin))!=-1){
如果(sread>0){
添加元素(第二,sline);
}
自由(斯林);
}
出售(“结束”);
}
int main(){
使用_输入_数组();
}

另一个问题是,我的输入字符串是一个字符数组,但我的结构是无类型的,所以它需要一个空指针。我可以创建一个
int
double
等数组来执行转换,但这也意味着有一个固定的大小。我正在考虑实现自己的转换函数,并在将元素插入数组之前调用它。但我真的不知道从哪里开始。。。有什么建议吗?谢谢。

像这样的东西可以用。
getline
只需要一个指针。由于指针被赋值为
array->memory[++array->index]=data需要为每个迭代分配更多内存。将
line
设置为NULL,将
len
设置为零。
当输入空行时考虑断开循环。代码>'\n'==行[0]

自由
在最末端

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);

像这样的事情可能会奏效。
getline
只需要一个指针。由于指针被赋值为
array->memory[++array->index]=data需要为每个迭代分配更多内存。将
line
设置为NULL,将
len
设置为零。
当输入空行时考虑断开循环。代码>'\n'==行[0]

自由
在最末端

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);

正确,但即使传递正确的参数也不能解决问题。我的想法不是释放数组,而是释放我用作缓冲区的
,方法是使用
clearr()
使用ctrl-dWell操作
clearr()
效果良好,关于:
array->memory=realloc(array->memory,toallocate)调用
realloc()
时,始终将返回值分配给临时指针。然后检查(!=NULL)临时指针。如果为NULL,则
realloc()
失败,因此处理错误。否则,将临时指针指定给
数组->内存
。因为如果
realloc()
失败,返回的值直接分配给
数组->内存
,则分配内存的指针丢失,导致无法恢复的内存泄漏,但即使传递正确的参数也不能解决问题我的想法不是释放数组,但是为了释放
我使用ctrl-dWell作为缓冲区,使用
clearerr()
操作很好:
array->memory=realloc(array->memory,toallocate)调用
realloc()
时,始终将返回值分配给临时指针。然后检查(!=NULL)临时指针。如果为NULL,则
realloc()
失败,因此处理错误。否则,将临时指针指定给
数组->内存
。因为如果
realloc()
失败,并且返回的值直接分配给
数组->内存
,那么指向已分配内存的指针将丢失,从而导致无法恢复的内存泄漏