c-为什么这个结构数组覆盖char*而不覆盖int



我写了一个程序,它利用结构数组来维护一种";数据库";具有不同选项的程序;数据库";。

如果用户输入,程序有4种操作模式:

  1. CCD_ 1数据可以插入到";数据库">
  2. CCD_ 2搜索";数据库";对于具有项目零件号的零件
  3. 'u'基于项目的零件号更新数据库中的某些内容
  4. 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()

最新更新