我已经试了几个小时让这个函数正常工作了。任务如下:
添加:请求零件名称、价格和数量。将信息保存到动态分配的结构数组中。一次最多可以为3个结构分配空间。您需要根据需要动态创建更多内存。使用这个结构(如果你想的话,你可以使用typedef):
到目前为止,我的代码是
typedef struct {
char* name;
float price;
int quantity;
}part;
void add(part *item, int *part_count)
{
//char temp[100];
if (!item){
item = malloc(sizeof(part)*3);
}
else{
item = realloc(item, sizeof(part) * ((*part_count*3) + 1));
}
item[*part_count].name = malloc(sizeof(char)*64); // max of 64 characters
printf("Please enter item name: n");
//fgets(temp, strlen(temp), stdin);
//sscanf(temp, "%s", item[*part_count].name);
scanf("%64s", item[*part_count].name);
printf("Please enter item price: n");
//fgets(temp, strlen(temp), stdin);
//sscanf(temp, "%f", &item[*part_count].price);
scanf("%f", &item[*part_count].price);
printf("Please enter item quantity: n");
//fgets(temp, strlen(temp), stdin);
//sscanf(temp, "%d", &item[*part_count].quantity);
scanf("%d", &item[*part_count].quantity);
*part_count = *part_count+ 1;
}
我曾尝试使用fgets()
和sscanf()
进行输入,但使用该代码时,它从不允许用户输入数据,然后结束函数。
我认为问题在于我的内存分配,因为当我尝试对数组执行任何操作(如打印内容)时,会出现分段错误。
假设,第一次调用add()时,项将为NULL,并进行其初始分配;随后调用realloc,使数组的大小是所需大小的3倍(我认为这不是您真正想要的)。
但是,与项匹配的参数不会因对add()的调用而更改,因此它保持为NULL,并且对add(()的每次调用都像是初始调用一样,为3个结构体分配空间(当您添加第4个结构体时,这将是一个问题)。
您可以将项设为**部分,并在当前使用部分的任何位置使用*部分,以便保留指针的新值(您将传递*部分的地址作为参数)。或者使用item的新值作为函数的返回值,这是一个更干净的IMHO。(这是参考参数派上用场的地方,但C没有这样的东西。)
您的函数有一个不可能的接口。它接受一个part *
指针。此指针按值进入函数。在您分配给它的函数内部,通过malloc
或realloc
调用。但是调用者将看不到这个更新的值。当函数返回时,您分配的内存已经泄漏,调用方具有原始指针值(可能为null)。
此外,最好用一个结构封装动态数组。您有一个"部分计数"变量,它本身就是松散的,必须与数组一起传递到各处,以跟踪其大小。把它们包装在一起怎么样:
typedef struct part_list {
struct part *part;
int count;
} part_list;
现在有一个函数来初始化空的零件列表。想要使用其他part_list
函数的每个人都必须调用此。
void part_list_init(part_list *pl)
{
pl->part = 0;
pl->count = 0;
}
然后编写添加部件的函数。
int part_list_add(part_list *pl)
{
part_list *p;
int index = pl->count++; /* increment count, keep old value */
/* realloc accepts a null pointer and then behaves like malloc */
p = realloc(pl->part, sizeof *pl->part * pl->count);
if (p == 0)
return 0; /* failed to allocate/extend array */
p1->part = p;
if ((pl->part[index].name = malloc(64)) == 0) {
pl->count = index; /* roll back the count: we didn't really allocate this part */
return 0;
}
/* your code, updated with pl-> access */
printf("Please enter item name: n");
scanf("%63s", pl->part[index].name); /* 63s not 64s!!! One byte for NUL char! */
printf("Please enter item price: n");
scanf("%f", &pl->part[index].price); /* check the return value of scanf!!! */
printf("Please enter item quantity: n");
scanf("%d", &pl->part[index].quantity);
return 1; /* 1 means success */
}