Guides:C/C Crash Course/Simple Address Book Example
From CoderGuide
Simple Address Book Example
Now that we understand how to use Structures, we can create a program that does something useful. It's a simple address book program:
/*******************phonebook.c -- a simple phone book program demonstrating the useof structures.********************/#include <stdio.h>#include <string.h>#define ENTRIES 20struct Record{
char name[40];
struct {
unsigned char year; /*years after 1900*/
char month;
char day;
}dob;
char phone[20];
}records[ENTRIES];
char chget();
void display(struct Record *);
void edit(struct Record *);
void list();
/*************** chget() ***************/char chget(){
char ch,x;
x=ch=getchar();
for(;x!='\n';x=getchar());
return ch;
}/*end chget()*/
/************** main() **************/int main(void){
char cmd;
int index;
/* Initialize array*/for(index=0;index<ENTRIES;index++){
records[index].name[0]=0;
records[index].phone[0]=0;
records[index].dob.year=0;
records[index].dob.month=0;
records[index].dob.day=0;
}/*end for(..I<ENTRIES,, */
index=0;
do{
int x; /*a temporary variable*/
printf("\nRECORD %02d OF %02d\n",index,ENTRIES-1);
display(&records[index]);
puts("\n(E)dit Entry");
puts("(N)ext Entry");
puts("(P)revious Entry");
puts("(L)ist entries (brief)");
puts("(Q)uit");
printf("\nCommand:");
cmd=chget();
/*process the command*/switch(cmd){
case 'E':
case 'e':
edit(&records[index]);
break;
case 'N':
case 'n':
index++;/*loop around if we've come to theend*/if(index>ENTRIES)index=0;
break;
case 'P':
case 'p':
index--;/*loop around if we've come to theend*/if(index<0)index=ENTRIES-1;
break;
case 'L':
case 'l':
list();
break;
case 'Q':
case 'q': break;
default:
puts("BAD COMMAND");
break;
} /*end switch(ch)*/
}while(cmd!='q' && cmd!='Q');
} /*end main()*/
/************** list() **************/void list(){
int x;
puts("*** LISTING ***");
for(x=0;x<ENTRIES;x++){
printf("%02d:%-40s|%-20s|", x,records[x].name,
records[x].phone);
/*we need to type cast these as ints to ensure theyare passed to printf integers*/printf("%04d-%02d-%02d\n",
(int)records[x].dob.year+1900,
(int)records[x].dob.month,
(int)records[x].dob.day);
}/*end for()*/
printf("** Pause **");
chget();
}/* end list*/
/***************** display() *****************/void display(struct Record *r){
int x;
/*print out a bar of stars*/for(x=0;x<60;x++)putchar('*');
putchar('\n');
printf("Name: %s\nPhone:%s\n",r->name,r->phone);
printf("DOB:%04d-%02d-%02d\n", (int)r->dob.year+1900,
(int)r->dob.month, (int)r->dob.day);
for(x=60;x;x--)putchar('*'); /*draw a bar of 60 stars*/
putchar('\n');
}/*end display()*/
/************** edit() **************/void edit(struct Record *r){
char s[128];
int i;
printf("Name:");
/*You should never use gets() in a program that matters */gets(s);
s[39]=0; /*Ensure the null terminator is in the right place*/
strcpy(r->name,s);
printf("Phone:");
gets(s);
s[19]=0;
strcpy(r->phone,s);
puts("--Birthday--");
printf("Year:");
gets(s);
i=atoi(s);
if(i>=1900)i-=1900;
r->dob.year=i;
printf("Month:");
gets(s);
r->dob.month=atoi(s);
printf("Day:");
r->dob.day=atoi(gets(s)); /*Yup, you can do that too*/
}/*end edit()*/
Now, this program has two limitations:
- You can't save your database and load it later.
- The program allows for only a fixed number of entries.
The first issue we'll resolve in the section on File I/O operations. The next issue can be delt with in a few ways, but all of those methods require dynamic memory allocation, and the use of pointers.

