/*******************************************************************/ /* NAMES.C */ /* */ /* This example shows how easy it is to write a program for an */ /* online address book using the B-PLUS file indexing toolkit. */ /* The program creates a file of names, addresses, and telephone */ /* numbers. A record is displayed on the screen by entering part */ /* or all of the name. Although the program is usefully as written */ /* it has purposely been kept simple. You may want to add new */ /* features to the progran. */ /* */ /********************************************************************/ #include <stdio.h> #include <string.h> #include "bplus.h" typedef struct /* Here is the address record definition */ { char lastname[16]; /* last name */ char firstname[16]; /* first name */ char address1[31]; /* first address line */ char address2[31]; /* second address line */ char city[21]; /* the city */ char state[3]; /* the state */ char zipcode[6]; /* postal zip code */ char telephone[14]; /* telephone number */ } ADDRESS; IX_DESC nameindex; /* index file variable */ FILE *namefile; /* data file pointer */ ADDRESS person; /* data record variable */ void openfiles(void); void closefiles(void); int addrecord(void); void getstring(char*, int); void newaddress(void); void printname(ENTRY*); void getname(void); void nextname(void); void listnames(void); void openfiles() /* If the file NAMES.DAT already exist, open the index and data */ /* file. Otherwise, these files are created. */ { if ((namefile = fopen("names.dat","r+")) != NULL) open_index("names.idx", &nameindex, 1); /* open index file */ else { namefile = fopen("names.dat","w+"); /* create data file */ if (namefile == NULL) { printf("Unable to open namefile\n"); exit(1); } make_index("names.idx", &nameindex, 1); /* creat index file */ } /* allow duplicate keys */ } /* openfiles */ void closefiles() /* close all files and exit */ { fclose(namefile); close_index(&nameindex); exit(0); } /* closefiles */ int addrecord() /* add a new address to the data file - add index to index file */ { ENTRY ee; char name[32]; int ret; ret = fseek(namefile, 0L, SEEK_END); /* seek to end of datafile */ if (ret == 0) { strcpy(ee.key, person.lastname); /* key is last name followed */ strcat(ee.key, person.firstname); /* first name. Capitalize */ strupr(ee.key); /* and copy to ee.key. */ ee.recptr = ftell(namefile); /* get position in datafile */ if (ee.recptr != -1L) { if (add_key(&ee, &nameindex) == IX_OK) /* add key to index */ { fwrite(&person,sizeof(person),1,namefile); /* add address */ return (IX_OK); } } } else printf("Seek error - data file"); return (IX_FAIL); } /* addrecord */ void getstring(mes, length) char *mes; int length; /* input a string and check that it is not too long */ { char message[80]; gets(message); if (strlen(message) > length) message[length] = '\0'; strcpy(mes,message); } /* getstring */ void newaddress() /* add new address records */ { while (1) { printf("\n\nLast Name : "); getstring(person.lastname,15); if ( strlen(person.lastname) > 0) /* quit if no last name */ { printf("First Name : "); getstring(person.firstname,15); printf("Address Line 1 : "); getstring(person.address1,30); printf("Address Line 2 : "); getstring(person.address2,30); printf("City : "); getstring(person.city,20); printf("State : "); getstring(person.state,2); printf("Zip Code : "); getstring(person.zipcode,5); printf("Telephone : "); getstring(person.telephone,13); addrecord(); /* update data and index files */ printf("\n"); } else return ; } } /* newaddress */ void printname(e) ENTRY *e; /* retrieve a data record and print it on the screen */ { int ret; /* seek to the record address stored in ENTRY e->recptr */ ret = fseek(namefile, e->recptr, SEEK_SET); if (ret == 0) /* if OK read the record and display */ { fread(&person,sizeof(person),1,namefile); printf("\n\n %s %s" , person.firstname,person.lastname); printf("\n %s", person.address1); if (strlen(person.address2) > 0) printf("\n %s", person.address2); printf("\n %s, %s %s", person.city,person.state,person.zipcode); printf("\n %s\n", person.telephone); } else printf("Seek error - data file"); } /* printname */ void getname() /* Get an address record by entering part or all of name */ /* Enter last name first then first name with no spaces */ { ENTRY ee; printf("\n\nEnter name: "); gets(ee.key); /* make all upper case letters and copy to ee.key */ strupr(ee.key); /* use locate_key instead of find_key so an exact match not required */ if (locate_key(&ee, &nameindex) != EOIX) printname(&ee); else printf("No key this large in index file\n"); } /* getname */ void nextname() /* display the next address in the address file */ { ENTRY ee; if (next_key(&ee, &nameindex) == IX_OK) printname(&ee); else printf("\nEnd of index file\n"); } /* nextname */ void listnames() /* list all the names in the address file */ { ENTRY ee; first_key(&nameindex); while (next_key(&ee, &nameindex) == IX_OK) printname(&ee); } /* listnames */ main() /* Here is the main program loop */ { char cmd; int done; done = 0; openfiles(); do { printf("\nCommand: A (Add Name), F (Find), N (Next), L (List), Q (Quit): "); cmd = toupper(getche()); switch (cmd) { case 'A': newaddress(); break; /* add a name to address file */ case 'F': getname(); break; /* find an address */ case 'N': nextname(); break; /* display next address in file */ case 'L': listnames(); break; /* display all addresses */ case 'Q': closefiles(); /* quit and close files */ } } while (!done); } /* main */