I have tried multiple methods for a long time but it didn't work, the output automatically updates all previously entered values for the name.
The find
method is not required to be checked, but the first display itself provides invalid output:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int phone;
char *name;
} phonecontact;
phonecontact *create(phonecontact *p, int phone, char name[], int i) {
(p i)->name = (char *)calloc(10, sizeof(char));
(p i)->name = name;
(p i)->phone = phone;
printf("\n%s\n", (p i)->name);
return p;
}
void display(phonecontact *p, int i) {
printf("Name : %s , Phone number : %d\n", p[i].name, p[i].phone);
}
int find(phonecontact *p, char name[], int *num) {
int phone, i = 0;
for (i = 0; i < *num; i ) {
if (strcmp(p[i].name, name) == 1)
display(p, i);
return 1;
}
p = (phonecontact *)realloc(p, (*num) * sizeof(phonecontact));
printf("Enter phone number for entered person : ");
scanf("%d", &phone);
p = create(p, phone, name, i 1);
return 0;
}
int main() {
int num, phone;
char name[30];
printf("Enter number of contacts : ");
scanf("%d", &num);
phonecontact *p;
p = (phonecontact *)calloc(num, sizeof(phonecontact));
for (int i = 0; i < num; i ) {
printf("Enter name : ");
scanf("%s", name);
printf("Enter phone number : ");
scanf("%d", &phone);
p = create(p, phone, name, i);
}
printf("\n%s\n", (p)->name);
printf("\n%s\n", (p 1)->name);
printf("\n%s\n", (p 2)->name);
for (int i = 0; i < num; i ) {
display(p, i);
}
printf("Enter name of contact : ");
scanf("%s", &name);
find(p,name, &num);
}
CodePudding user response:
There are many problems in the code:
- For each contact to have its own
name
string, you must allocate a copy of thecreate()
string argument:
phonecontact *create(phonecontact *p, int phone, const char *name, int i) {
p[i].name = strdup(name);
p[i].phone = phone;
printf("\n%s\n", p[i].name);
return p;
}
- the function
strcmp()
returns0
when the strings compare equal, a negative value if the first argument compares less than the second in lexicographical order and a value greater than zero otherwise.
You should use if (strcmp(p[i].name, name) == 0)
and return 1 only if the strings compare equal.
It is confusing for a function named
find()
to append a new entry in the array.The array reallocated by
find()
is not passed back to the caller, and the previous pointer may have become invalid, causing undefined behavior.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int phone;
char *name;
} phonecontact;
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
void init_contact(phonecontact *p, int phone, const char *name) {
p->name = strdup(name);
p->phone = phone;
}
void display_contact(const phonecontact *p) {
printf("Name: %s, Phone number: %d\n", p->name, p->phone);
}
int add_contact(phonecontact **pp, int *pnum, const char *name) {
int phone;
int num = *pnum;
phonecontact *p = *pp;
for (int i = 0; i < num; i ) {
if (strcmp(p[i].name, name) == 1) {
display_contact(&p[i]);
return 1;
}
}
/* reallocate the contact array */
p = (phonecontact *)realloc(p, (num 1) * sizeof(*p));
if (p == NULL) {
printf("cannot reallocate contact array\n");
return -1;
}
printf("Enter phone number for entered person: ");
while (scanf("%d", &phone) != 1) {
printf("Invalid input. Try again: ");
if (flush_input() == EOF)
return -1;
}
init_contact(&p[num], phone, name);
*pnum = num 1;
*pp = p;
return 0;
}
int main() {
int num, phone;
char name[30];
printf("Enter number of contacts : ");
if (scanf("%d", &num) != 1 || num < 0) {
fprintf(stderr, "invalid input\n");
return 1;
}
phonecontact *p = calloc(num, sizeof(*p));
if (p == NULL) {
fprintf(stderr, "memory allocation error\n");
return 1;
}
for (int i = 0; i < num; i ) {
printf("Enter name: ");
if (scanf(" )[^\n]", name) != 1) {
fprintf(stderr, "invalid input\n");
return 1;
}
printf("Enter phone number: ");
if (scanf("%d", &phone) != 1)
fprintf(stderr, "invalid input\n");
return 1;
}
init_contact(&p[i], phone, name);
}
for (int i = 0; i < num; i ) {
display_contact(&p[i]);
}
printf("Enter name of contact: ");
if (scanf(" )[^\n]", &name) == 1)
add_contact(&p, *num, name);
return 0;
}