Address Book Implementation
Address book requirements
Implement an address book;
The address book can be used to store the information of 1000 people. Each person's information includes: name, gender, age, telephone and address
Provide method:
Add contact information
Delete specified contact information
Find specified contact information
Modify the specified contact information
Show all contact information
Empty all contacts
Sort all contacts by name
Realization idea
The implementation of address book uses three functions,
- test.c complete the main frame of the address book, including the cycle of menu and selection functions
- contact.h contains test The address book function declaration and structure variable declaration to be used in C c
- Complete the description of contact Definition of address book function declared in H
Simple implementation
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include"contact.h" void menu() { printf("******************************\n"); printf("***** 1.add 2.delete***\n"); printf("***** 3.search 4.sub ***\n"); printf("***** 5.sort 6.print ***\n"); printf("***** 0.exite ***\n"); printf("******************************\n"); printf("******************************\n"); } enum function { excite, add, delete, search, sub, sort, print }; int main() { int input = 0; struct peopleinfo data[MAX_data]; initcontact(&con); do { menu(); scanf_s("%d", &input); switch (input) { case add: addcontact(&con); break; case excite: exitcon(&con); break; case delete: delecon(&con); break; case search: searchcon(&con); break; case sub: break; case sort: sortcon(&con); break; case print: printcon(&con); break; default: printf("Reenter the correct options"); } } while (input); }
The advantage of defining enumeration variables is that you can more intuitively see the executed functions in the branch statements
contact.h
#define _CRT_SECURE_NO_WARNINGS 1 #include<string.h> #include<stdio.h> #define MAX 20 #define MAX_data 10 struct peopleinfo { char name[MAX]; char gender[MAX]; int age; char tele[MAX]; char address[MAX]; }data[MAX_data]; struct contact { struct peopleinfo data[MAX_data]; int sz; }con; void initcontact(struct contact* p); int addcontact(struct contact* p); void printcon(struct contact* p); void delecon(struct contact* p); void searchcon(struct contact* p); void sortcon(struct contact* p); void subcon(struct peopleinfo* p1,struct peopleinfo* p2); void exitcon(struct contact* p);
It is very important to record how many contacts are stored in the address book, because we define a structure array struct contact data [] if we don't know how many contacts are in the data, we can't add, delete, query and modify them
contact.c
#define _CRT_SECURE_NO_WARNINGS 1 #pragma warning(disable:6031) #include"contact.h" void initcontact(struct contact* p) { memset(p, 0, sizeof(*p)); p->sz = 0; } void exitcon(struct contact* p) { memset(p, 0, sizeof(*p)); p->sz = 0; } int addcontact(struct contact* p) { if ((p->sz) >= MAX_data) { printf("The address book is full"); return 0; } printf("\n Please enter your name:"); scanf("%s", p->data[p->sz].name); printf("\n Please enter gender:"); scanf("%s", p->data[p->sz].gender); printf("\n Please enter age"); scanf("%d", &(p->data[p->sz].age)); printf("\n Please enter the phone number"); scanf("%s", p->data[p->sz].tele); printf("\n Please enter your address:"); scanf("%s", p->data[p->sz].address); p->sz++; return 0; } void printcon(struct contact* p) { for (int i = 0; i < p->sz; i++ ) { printf("%-7s\t%-5s\t%-2s\t%-5s\t%-5s\n", "full name", "Gender", "Age", "Telephone", "address"); printf("%-7s\t", p->data[i].name); printf("%-5s\t", p->data[i].gender); printf("%d\t", p->data[i].age); printf("%-5s\t", p->data[i].tele); printf("%-5s\t", p->data[i].address); printf("\n"); } } static int findbyname(char *p1,struct contact* p2) { for (int i = 0; i < p2->sz-1; i++) { int ret = strcmp(p1, p2->data[p2->sz-1].name); if (ret == 0) return p2->sz-1; } return 0; } void delecon(struct contact* p)//Delete function { if (p->sz < 1) printf("The address book is empty and cannot be deleted"); else { char name1[MAX]; printf("Enter the contact name to delete:"); scanf("%s", name1); int ret = findbyname(name1, p); if(ret==0) printf("There is no such person"); else { for (int z = ret; z < (p->sz-1 - ret); z++) { p->data[z] = p->data[z + 1]; } p->sz--; } } } void searchcon(struct contact* p) //Find function { printf("q Please enter a name to find:"); char name1[MAX]; scanf("%s", name1); for (int i = 0; i < p->sz-1; i++) { int ret = strcmp(name1, p->data[i].name); if (ret == 0) { printf("%-7s\t%-5s\t%-2s\t%-5s\t%-5s\n", "full name", "Gender", "Age", "Telephone", "address"); printf("%-7s\t", p->data[i].name); printf("%-5s\t", p->data[i].gender); printf("%d\t", p->data[i].age); printf("%-5s\t", p->data[i].tele); printf("%-5s\t", p->data[i].address); printf("\n"); break; } } } void sortcon(struct contact* p) //Sorting function { for (int i = 0; i < p->sz-1; i++) { for (int j = 0; j < p->sz - i-1; j++) { int ret = strcmp(p->data[i].name, p->data[i + 1].name); if (ret > 0) { subcon(&(p->data[i]), &(p->data[i + 1])); } } } printcon(p); } void subcon(struct peopleinfo* p1, struct peopleinfo* p2) //Use byte by byte copy to complete the copy { char a=0; int size = sizeof(data[0]); for (int i = 0; i < size; i++) { a = ((char*)p1)[i]; ((char*)p1)[i] = ((char*)p2)[i]; ((char*)p2)[i] = a; } }
But if you write this to the compiler, the probability can be compiled. However, there is a defect in this program, that is, there are 1000 people's information in the space just opened up, but if only 10 people's information is entered, the remaining space will be wasted, so it is most appropriate to use dynamic development
Dynamic memory improvement
If you have problems with dynamic memory development, you can refer to this blog Some understanding of dynamic memory management
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include"contact.h" void menu() { printf("******************************\n"); printf("***** 1.add 2.delete***\n"); printf("***** 3.search 4.sub ***\n"); printf("***** 5.sort 6.print ***\n"); printf("***** 0.exite ***\n"); printf("******************************\n"); printf("******************************\n"); } enum function { excite, add, delete, search, sub, sort, print }; int main() { int input = 0; struct peopleinfo data[MAX_data]; initcontact(&con); do { menu(); scanf_s("%d", &input); switch (input) { case add: addcontact(&con); break; case excite: exitcon(&con); break; case delete: delecon(&con); break; case search: searchcon(&con); break; case sub: break; case sort: sortcon(&con); break; case print: printcon(&con); break; default: printf("Reenter the correct options"); } } while (input); }
test. The function of C has no change compared with the original one
contact.h
#define _CRT_SECURE_NO_WARNINGS 1 #include<string.h> #include<stdio.h> #include<malloc.h> #define MAX 20 #define initial 3 / / the first three spaces #define ADDCA 2 / / 2 spaces added each time struct peopleinfo { char name[MAX]; char gender[MAX]; int age; char tele[MAX]; char address[MAX]; }; struct contact { struct peopleinfo *data; int sz; //How many contacts are there in the address book int capacity; //Open address book capacity }con; void initcontact(struct contact* p); int addcontact(struct contact* p); void printcon(struct contact* p); void delecon(struct contact* p); void searchcon(struct contact* p); void sortcon(struct contact* p); void subcon(struct peopleinfo* p1, struct peopleinfo* p2); void exitcon(struct contact* p);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1 #pragma warning(disable:6031) #include"contact.h" void initcontact(struct contact* p) { p->data = (struct peopleinfo*)malloc(initial*sizeof(struct peopleinfo));//Open up the initial three spaces if (p->data == NULL) { printf("initialization failed"); return; } else { p->sz = 0; p->capacity = initial; } } void exitcon(struct contact* p) { free(p->data); //Overall recycling space p->data = NULL; } int addcontact(struct contact* p) { //Check whether to expand the capacity if (p->sz == p->capacity) { struct peopleinfo* ptr = (struct peopleinfo*)realloc(p->data, (p->capacity+ADDCA) * sizeof(struct peopleinfo)); if (ptr == NULL) { printf("initialization failed"); return 0; } else { p->data = ptr; printf("Initialization succeeded"); p->capacity = p->capacity + ADDCA; } } printf("\n Please enter your name:"); scanf("%s", p->data[p->sz].name); printf("\n Please enter gender:"); scanf("%s", p->data[p->sz].gender); printf("\n Please enter age"); scanf("%d", &(p->data[p->sz].age)); printf("\n Please enter the phone number"); scanf("%s", p->data[p->sz].tele); printf("\n Please enter your address:"); scanf("%s", p->data[p->sz].address); p->sz++; return 0; } void printcon(struct contact* p) { for (int i = 0; i < p->sz; i++) { printf("%-7s\t%-5s\t%-2s\t%-5s\t%-5s\n", "full name", "Gender", "Age", "Telephone", "address"); printf("%-7s\t", p->data[i].name); printf("%-5s\t", p->data[i].gender); printf("%d\t", p->data[i].age); printf("%-5s\t", p->data[i].tele); printf("%-5s\t", p->data[i].address); printf("\n"); } } static int findbyname(char* p1, struct contact* p2) { for (int i = 0; i < p2->sz - 1; i++) { int ret = strcmp(p1, p2->data[p2->sz - 1].name); if (ret == 0) return p2->sz - 1; } return 0; } void delecon(struct contact* p) { if (p->sz < 1) printf("The address book is empty and cannot be deleted"); else { char name1[MAX]; printf("Enter the contact name to delete:"); scanf("%s", name1); int ret = findbyname(name1, p); if (ret == 0) printf("There is no such person"); else { for (int z = ret; z < (p->sz - 1 - ret); z++) { p->data[z] = p->data[z + 1]; } p->sz--; } } } void searchcon(struct contact* p) { printf("q Please enter a name to find:"); char name1[MAX]; scanf("%s", name1); for (int i = 0; i < p->sz - 1; i++) { int ret = strcmp(name1, p->data[i].name); if (ret == 0) { printf("%-7s\t%-5s\t%-2s\t%-5s\t%-5s\n", "full name", "Gender", "Age", "Telephone", "address"); printf("%-7s\t", p->data[i].name); printf("%-5s\t", p->data[i].gender); printf("%d\t", p->data[i].age); printf("%-5s\t", p->data[i].tele); printf("%-5s\t", p->data[i].address); printf("\n"); break; } } } void sortcon(struct contact* p) { for (int i = 0; i < p->sz - 1; i++) { for (int j = 0; j < p->sz - i - 1; j++) { int ret = strcmp(p->data[i].name, p->data[i + 1].name); if (ret > 0) { subcon(&(p->data[i]), &(p->data[i + 1])); } } } printcon(p); } void subcon(struct peopleinfo* p1, struct peopleinfo* p2) { char a = 0; int size = sizeof(struct peopleinfo); for (int i = 0; i < size; i++) { a = ((char*)p1)[i]; ((char*)p1)[i] = ((char*)p2)[i]; ((char*)p2)[i] = a; } }
Document storage improvement
If you don't know much about the file, you can refer to this blog c language file operation
There are only two points to change:
- First, the initialization function initcontact copies the data in the file to memory after applying for the initialization space. Here, copying also involves checking the capacity
- Then, in the last exit address book function, the exite function writes the data stored in memory to the file
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include"contact.h" void menu() { printf("******************************\n"); printf("***** 1.add 2.delete***\n"); printf("***** 3.search 4.sub ***\n"); printf("***** 5.sort 6.print ***\n"); printf("***** 0.exite ***\n"); printf("******************************\n"); printf("******************************\n"); } enum function { excite, add, delete, search, sub, sort, print }; int main() { int input = 0; initcontact(&con); do { menu(); scanf_s("%d", &input); switch (input) { case add: addcontact(&con); break; case excite: exitcon(&con); break; case delete: delecon(&con); break; case search: searchcon(&con); break; case sub: break; case sort: sortcon(&con); break; case print: printcon(&con); break; default: printf("Reenter the correct options"); } } while (input); }
contact.c
#define _CRT_SECURE_NO_WARNINGS 1 #define _CRT_SECURE_NO_WARNINGS 1 #pragma warning(disable:6031) #include"contact.h" void checkcapcity(struct contact* p) { if (p->sz == p->capacity) { struct peopleinfo* ptr = (struct peopleinfo*)realloc(p->data, (p->capacity + ADDCA) * sizeof(struct peopleinfo)); if (ptr == NULL) { printf("initialization failed"); return; } else { p->data = ptr; printf("Initialization succeeded"); p->capacity = p->capacity + ADDCA; } } } void file_read(struct contact* p) { FILE* pf = fopen("contact.txt", "r"); if (pf == NULL) printf("Failed to read the file. Please read it again"); else { struct peopleinfo temp; while(fread(&temp, sizeof(struct peopleinfo), 1, pf)) //It is important to use the return value of the fread function to check whether all the data in the file is read. { checkcapcity(p); p->data[p->sz] = temp; p->sz++; } } } void initcontact(struct contact* p) { p->data = (struct peopleinfo*)malloc(initial * sizeof(struct peopleinfo)); if (p->data == NULL) { printf("initialization failed"); return; } else { p->sz = 0; p->capacity = initial; } file_read(p); } void exitcon(struct contact* p) { FILE* pf = fopen("contact.txt", "w"); if (p == NULL) printf("Failed to save file"); else { for (int i = 0; i < p->sz; i++) { fwrite(p->data + i, sizeof(struct peopleinfo), 1, pf); } } fclose(pf); free(p->data); p->data = NULL; } int addcontact(struct contact* p) { if (p->sz == p->capacity) { struct peopleinfo* ptr = (struct peopleinfo*)realloc(p->data, (p->capacity + ADDCA) * sizeof(struct peopleinfo)); if (ptr == NULL) { printf("initialization failed"); return 0; } else { p->data = ptr; printf("Initialization succeeded"); p->capacity = p->capacity + ADDCA; } } printf("\n Please enter your name:"); scanf("%s", p->data[p->sz].name); printf("\n Please enter gender:"); scanf("%s", p->data[p->sz].gender); printf("\n Please enter age"); scanf("%d", &(p->data[p->sz].age)); printf("\n Please enter the phone number"); scanf("%s", p->data[p->sz].tele); printf("\n Please enter your address:"); scanf("%s", p->data[p->sz].address); p->sz++; return 0; } void printcon(struct contact* p) { for (int i = 0; i < p->sz; i++) { printf("%-7s\t%-5s\t%-2s\t%-5s\t%-5s\n", "full name", "Gender", "Age", "Telephone", "address"); printf("%-7s\t", p->data[i].name); printf("%-5s\t", p->data[i].gender); printf("%d\t", p->data[i].age); printf("%-5s\t", p->data[i].tele); printf("%-5s\t", p->data[i].address); printf("\n"); } } static int findbyname(char* p1, struct contact* p2) { for (int i = 0; i < p2->sz - 1; i++) { int ret = strcmp(p1, p2->data[p2->sz - 1].name); if (ret == 0) return p2->sz - 1; } return 0; } void delecon(struct contact* p) { if (p->sz < 1) printf("The address book is empty and cannot be deleted"); else { char name1[MAX]; printf("Enter the contact name to delete:"); scanf("%s", name1); int ret = findbyname(name1, p); if (ret == 0) printf("There is no such person"); else { for (int z = ret; z < (p->sz - 1 - ret); z++) { p->data[z] = p->data[z + 1]; } p->sz--; } } } void searchcon(struct contact* p) { printf("q Please enter a name to find:"); char name1[MAX]; scanf("%s", name1); for (int i = 0; i < p->sz - 1; i++) { int ret = strcmp(name1, p->data[i].name); if (ret == 0) { printf("%-7s\t%-5s\t%-2s\t%-5s\t%-5s\n", "full name", "Gender", "Age", "Telephone", "address"); printf("%-7s\t", p->data[i].name); printf("%-5s\t", p->data[i].gender); printf("%d\t", p->data[i].age); printf("%-5s\t", p->data[i].tele); printf("%-5s\t", p->data[i].address); printf("\n"); break; } } } void sortcon(struct contact* p) { for (int i = 0; i < p->sz - 1; i++) { for (int j = 0; j < p->sz - i - 1; j++) { int ret = strcmp(p->data[i].name, p->data[i + 1].name); if (ret > 0) { subcon(&(p->data[i]), &(p->data[i + 1])); } } } printcon(p); } void subcon(struct peopleinfo* p1, struct peopleinfo* p2) { char a = 0; int size = sizeof(struct peopleinfo); for (int i = 0; i < size; i++) { a = ((char*)p1)[i]; ((char*)p1)[i] = ((char*)p2)[i]; ((char*)p2)[i] = a; } }
contact.h
#define _CRT_SECURE_NO_WARNINGS 1 #define _CRT_SECURE_NO_WARNINGS 1 #include<string.h> #include<stdio.h> #include<malloc.h> #define MAX 20 #define initial 3 #define ADDCA 2 struct peopleinfo { char name[MAX]; char gender[MAX]; int age; char tele[MAX]; char address[MAX]; }; struct contact { struct peopleinfo* data; int sz; int capacity; }con; void initcontact(struct contact* p); int addcontact(struct contact* p); void printcon(struct contact* p); void delecon(struct contact* p); void searchcon(struct contact* p); void sortcon(struct contact* p); void subcon(struct peopleinfo* p1, struct peopleinfo* p2); void exitcon(struct contact* p);