我写了一个程序,它利用结构数组来维护一种";数据库";具有不同选项的程序;数据库";。
如果用户输入,程序有4种操作模式:
- CCD_ 1数据可以插入到";数据库">
- CCD_ 2搜索";数据库";对于具有项目零件号的零件
'u'
基于项目的零件号更新数据库中的某些内容- CCD_ 4打印整个";数据库">
这是由3个文件组成的代码:
数据库.h:
#ifndef DATABASE
#define DATABASE
struct db
{
int part_number;
char *part_name;
int part_quantity;
};
extern struct db database[50];
extern void insert(int i);
extern int search(int i);
extern int update(int i);
extern int print(int i);
#endif
数据库.c
#include <string.h>
#include <stdio.h>
#include "database.h"
struct db database[50];
void insert(int i)
{
char name_of_part[21], c;
printf("%pn", &database[i].part_name);
printf("n");
printf("Enter a part number: ");
scanf("%d", &database[i].part_number);
while((c = getchar()) != 'n' && c != EOF); // flush stdin
printf("Enter a part name: ");
fgets(name_of_part, 20, stdin);
printf("Enter quantity of part: ");
scanf("%d", &database[i].part_quantity);
database[i].part_name = name_of_part;
printf("n");
}
int search(int i)
{
int input;
printf("n");
printf("Enter a part number: ");
scanf("%d", &input);
for (int j = 0; j <= i; j++)
{
if (database[j].part_number == input)
{
printf("Part name: %sn", database[j].part_name);
printf("Quantity on hand: %dn", database[j].part_quantity);
return 0;
}
}
printf("Part not found.n");
}
int update(int i)
{
int input, quantity;
printf("n");
printf("Enter part number: ");
scanf("%d", &input);
for (int j = 0; j <= i; j++)
{
if (database[j].part_number == input)
{
printf("Enter part quantity: ");
scanf("%d", &quantity);
database[j].part_quantity = quantity;
return 0;
}
}
printf("Part number not found.");
}
int print(int i)
{
for (int j = 0; j < i; j++)
{
printf("Part number: %dn Part name: %sn Part quantity: %dn", database[j].part_number, database[j].part_name,database[j].part_quantity);
}
}
main.c
#include <stdio.h>
#include <string.h>
#include "database.h"
int main()
{
int i = 0;
char code;
while (1)
{
printf("Enter a function code: ");
scanf(" %c", &code);
switch (code)
{
case 'i':
insert(i);
i += 1;
break;
case 's':
search(i);
break;
case 'u':
update(i);
break;
case 'p':
print(i);
break;
}
}
return 0;
}
我遇到的问题是,当我插入";数据库";,每个结构中的名称都会被覆盖。例如:
Enter a function code: i
Enter a part number: 111
Enter a part name: 111
Enter quantity of part: 111
Enter a function code: i
Enter a part number: 222
Enter a part name: 222
Enter quantity of part: 222
Enter a function code: p
Part number: 111
Part name: 222
Part quantity: 111
Part number: 222
Part name: 222
Part quantity: 222
Enter a function code:
正如你首先看到的,我在";数据库";,注意到";部件名称";其为";111〃;。
接下来,我将其他内容插入数据库这一次;部件名称";是";222";。
最后,我打印了整个";数据库";我感到困惑的是,为什么零件名称现在重叠了。但为什么会这样呢?所有其他成员(如partnumber和partquantity(在两次插入操作中都保持不变,那么为什么char*partname保持不变呢?我该怎么解决这个问题?
将part_name
成员声明为char *
,并在insert
函数中为其分配本地数组的地址。当函数返回时,该数组将超出范围,并且存储的指针将变为无效。随后尝试使用该指针会触发未定义的行为。
将part_name
更改为数组:
struct db
{
int part_number;
char part_name[21];
int part_quantity;
};
并直接写入:
printf("Enter a part name: ");
fgets(database[i].part_name, 21, stdin);
行
database[i].part_name = name_of_part;
很糟糕。这是为非静态局部变量分配一个指针。该变量在从函数返回时结束其生命,并且取消引用指向该函数的指针是非法的。
照片上的这个,你必须复制字符串。如果您的系统支持strdup()
,可以这样做:
database[i].part_name = strdup(name_of_part);
如果不支持'i'
0,或者你想坚持标准,你可以这样做:
database[i].part_name = malloc(strlen(name_of_part) + 1); /* +1 for ther terminating null-character */
if (database[i].part_name != NULL)
{
strcpy(database[i].part_name, name_of_part);
}
添加#include <stdlib.h>
以使用malloc()
。