I have a bunch of practice questions in Structures, all of which involve structures passed as pointers to function arguments. Now, I have a specific question at hand, which asks me to store some names and telephone numbers in a phone book structure. It reads as follows:
Write a C program that implements the following two functions. The function
readin()
reads a number of persons’ names and their corresponding telephone numbers, passes the data to the caller via the parameterp
, and returns the number of names that have entered. The character#
is used to indicate the end of user input. The functionsearch()
finds the telephone number of an input name target, and then prints the name and telephone number on the screen. If the input name cannot be found, then it will print an appropriate error message. The prototypes of the two functions are given below:
int readin(PhoneBk *p);
void search(PhoneBk *p, int size, char *target);
The structure definition for PhoneBk
is given below:
typedef struct {
char name[20];
char telno[20];
} PhoneBk;
The program template is as follows:
#include <stdio.h>
#include <string.h>
#define MAX 100
typedef struct {
char name[20];
char telno[20];
} PhoneBk;
int readin(PhoneBk *p);
void search(PhoneBk *p, int size, char *target);
int main() {
PhoneBk s[MAX];
char t[20];
int size;
size = readin(s);
printf("Enter search name: \n");
gets(t);
search(s, size, t);
return 0;
}
int readin(PhoneBk *p) {
/* Write your program code here */
}
void search(PhoneBk *p, int size, char *target) {
/* Write your program code here */
}
I'll have to compare strings twice in my program: one, to check if #
is entered as the name (in which case I'd like the program to jump straight to the search function without asking the phone number); and two, if the targeted name matches that in one of the phone book structures.
Now I am completely alien to the concept of structures being declared as arrays but passed as pointers, so I think the way to get the user input for the next record is by incrementing the pointer variable (here p
). For the get-the-records-until-#-is-entered function, I wrote this (using strcmp
):
int readin(PhoneBk *p) {
strcpy(p->name, "Test"); //To guarantee a character that is not #.
while (strcmp(p->name, "#") != 0) {
printf("Enter person name, # to stop.\n");
scanf("%s", p->name);
printf("Enter the telephone number.\n");
scanf("%s", p->telno);
p++;
}
return p;
}
My intention is to typecast p->name
as a string so that strcmp()
can work on it. But a warning is repeatedly shown:
warning: cast from pointer to integer of different size
warning: passing argument 1 of strcmp() makes pointer from integer without a cast
This error has been discussed many times on the forums (I searched), but nothing that I've seen really helps with this combination of structures and strcmp()
.
I gave up on strcmp()
entirely for the second function, the one that displays the record of a person if the targeted name is found, and so I used a loop to compare the strings directly.
void search(PhoneBk *p, int size, char *target) {
int i, flag = 1, strCompare;
char c1 = *(p->name), c2 = *target, p1 = p->name, p2 = target;
while (c1 != '\0' && c2 != '\0') { //Comparing strings.
strCompare = (int)(c1 - c2);
if (strCompare != 0)
break;
else {
p1++;
p2++;
}
}
for (i = 0; i < size; i++, p++) {
if (strCompare == 0) {
flag = 0;
printf("Name = %s, Tel. = %s\n", p->name, p->telno);
}
if (flag == 1)
printf("Name not found.\n");
}
}
But again I get a number of warnings.
warning: cast from pointer to integer of different size
warning: initialization makes pointer from integer without a cast
I really think my life would be easier if the structures were all passed as arrays, in which case I could simply iterate through the array of structures using a For loop and be done with it. This is what I've always done throughout high school, but now that I'm in university, I am forced to deal with structures passed as pointers.
How do I handle strcmp()
in this case? How can this be applied to any program with structures passed as pointers?