I have written a program which makes use of array of structures in order to maintain a sort of "database" program with different options that can be used to manipulate the "database".
The program has 4 modes of operation, if the user enters:
'i'
data can be inserted into the "database".'s'
searches the "database" for a part with a part number of a item.'u'
updates something in the database based on the part number of a item.'p'
prints the whole "database".
Here is the code which is made of 3 files:
database.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
database.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("%p\n", &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: %s\n", database[j].part_name);
printf("Quantity on hand: %d\n", 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: %d\n Part name: %s\n Part quantity: %d\n", 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;
}
The problem i have is that when i insert into the "database", the name in each structure gets overwritten. for example:
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:
As you can see first i insert something new in the "database", take note of the "Part name" which is "111".
Next i insert something else into the database this time the "Part name" is "222".
Lastly i print the whole "database" what i am confused about is why the part name has now overlapped. but why is this? all the other members such as the part_number and part_quantity remain intact in both insert operations so why does char *part_name stay the same ? and how do i fix this ?
You have the
part_name
member declared as achar *
and you assign to it the address of a local array in theinsert
function. When the function returns, that array goes out of scope and the stored pointer becomes invalid. Subsequently trying to use that pointer triggers undefined behavior.Change
part_name
to be an array:And write directly to that: