And look at other people's staring eyes like lamps and lanterns of will-o'-the-wisps, boldly go your night way. —— Shi Tiesheng
Table of contents
1. Preliminary preparation of the address book
4. And the required header files
2. The functions to be realized by the address book
1. Initialize the address book
6. Modify the specified contact
7. Sort contacts by first name
3. The complete code of the static address book
1. Change the members of the structure to pointers
2. Modify the initialization address book
3. Write a capacity-enhancing function
4. Exit the program and release the memory
5. The complete code of the optimized version
Foreword:
We need to use C language to simulate an address book that can be used to store the information of 100 people.
The information of each person includes: name, gender, age, phone number, and address.
Function introduction:
1. Add contacts
2. Display contacts
3. Delete contacts
4. Find specified contacts
5. Modify specified contacts
6. Use contact names to sort
7. Finally exit the address book and destroy it address book
After learning the sequence table of the data structure before , the address book is very simple.
1. Preliminary preparation of the address book
1. Create a file
When implementing the address book, we also divided the complete code into three files:
1.test.c: Test the related functions of the address book
2.Contact.h: function declaration
3.Contact.c: Implementation code of address book
2. Printing of the menu
For the implementation of the menu: increase the readability of the code for users , and see the menu, you can know what functions the address book has. So it's important to have a menu.
Printing of the menu:
void menu()
{
printf("***************************\n");
printf("****** 1.Add 2.Del *****\n");
printf("***** 3.Search 4.Modify ***\n");
printf("***** 5.Show 6.Sort *****\n");
printf("***** 0.Exit *************\n");
printf("***************************\n");
}
3. Use of enumeration
Using enumeration also increases the readability of our code , and we can know what functions to achieve when we see English.
We use the enumerated English to replace the numbers in the case statement.
enum option
{
Exit,//从0开始,依次往下递增1
Add,//1
Del,//2
Search,//3
Modify,//4
Show,//5
Sort//6
};
int main()
{
int input = 0;
do
{
menu();
printf("请你选择要实现的功能:>\n");
scanf("%d", &input);
switch (input)
{
case Add:
AddContact();
break;
case Del:
DelContact();
break;
case Search:
SearchContact();
break;
case Modify:
ModifyContact();
break;
case Show:
ShowContact();
break;
case Sort:
SortContact();
break;
case Exit:
DestroyContact();
printf("退出通讯录\n");
break;
}
} while (input);
return 0;
}
4. And the required header files
We use macros to define our
#pragma once
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 10
//使用结构体存储一个人的信息
typedef struct people
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tele[TELE_MAX];
char addr[ADDR_MAX];
}people;
typedef struct Contact
{
people data[MAX];//存储100个人的信息
int size;
}Contact;
2. The functions to be realized by the address book
1. Initialize the address book
Step 1: We use a memset function to assign 0 to each byte in the data array. That is what we usually call initialization.
void InitContact(Contact* ps)
{
ps->size = 0;
memset(ps->data, 0, sizeof(ps->data));
//将data数组里面的每个字节都初始化为0
}
2. Add contacts
Step 2: After completing the first step, we can create a function for adding contacts. This is very simple. We only need to access each element in the array in the address book structure and enter the corresponding value.
void AddContact(Contact* ps)
{
if (ps->size == MAX)
{
printf("通讯录已经满了,不能添加联系人了\n");
return;
}
printf("请你输入你要添加的名字:>");
scanf("%s", ps->data[ps->size].name);
printf("请你输入性别:>");
scanf("%s", ps->data[ps->size].sex);
printf("请你输入年龄:>");
scanf("%d", &(ps->data[ps->size].age));
printf("请你输入电话号码:>");
scanf("%s", ps->data[ps->size].tele);
printf("请你输入地址:>");
scanf("%s", ps->data[ps->size].addr);
ps->size++;
printf("添加成功\n");
}
3. Show contacts
Step 3: If we choose 5, we will display the added contacts. Note here that we use % -10s . nice.
void ShowContact(Contact* ps)
{
int i = 0;
printf("%-10s %-5s %-5s %-12s %-30s\n", "名字", "性别", "年龄", "电话", "地址");
for (i = 0; i < ps ->size; i++)
{
printf("%-10s %-5s %-5d %-12s %-30s\n", ps->data[i].name,
ps->data[i].sex, ps->data[i].age, ps->data[i].tele, ps->data[i].addr);
}
}
4. Delete contacts
Step 4: We input the name of the contact to be deleted, and then use the strcmp function to compare. If found, our purpose is to delete him from this address book. The method we use is to make all the contents behind the array go to Move forward one bit to overwrite the contact to be deleted.
Here we use to find contacts, and later we will also use to find contacts. Here we encapsulate the search contacts as a function . Every time we want to use it, we can directly call this function.
Function to find a contact:
int FindByname(Contact* ps, char name[])
{
int i = 0;
for (i = 0; i < ps->size; i++)//使用一个for循环遍历整个数组
{
if (0==strcmp(name, ps->data[i].name))//strcmp的返回值是0就说明找到了
{
return i;
}
}
return -1;//没找到就返回-1
}
Function to delete contacts:
void DelContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
if (ps->size == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
printf("请你输入要删除联系人的名字:>");
scanf("%s", name);
int pos = FindByname(ps, name);
if (pos == -1)
{
printf("你要删除的人不存在\n");
return;
}
int i = 0;
for (i = pos; i < ps->size - 1; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->size--;
printf("删除成功\n");
}
5. Find the specified contact
The codes implemented to find a specified contact and delete a contact are actually similar, and the search function must be called. Enter the name of the contact you want to find, and then use a for loop to traverse the entire array . If the person you want to find is found in the array, return his subscript. Finally , use the subscript to print out the found contacts .
void SearchContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
printf("输入你要查找联系人的名字:>");
scanf("%s", name);
int pos= FindByname(ps, name);
if (pos == -1)
{
printf("你要查找的联系人不存在\n");
return;
}
printf("这是你要查找的人:>\n");
printf("%-10s %-5s %-5s %-12s %-30s\n", "名字", "性别", "年龄", "电话", "地址");
printf("%-10s %-5s %-5d %-12s %-30s\n", ps->data[pos].name,
ps->data[pos].sex, ps->data[pos].age, ps->data[pos].tele, ps->data[pos].addr);
}
6. Modify the specified contact
This is also very simple, which is roughly the same as the previous content.
void ModifyContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
printf("输入你要修改联系人的名字\n");
scanf("%s", name);
int pos = FindByname(ps, name);
if (pos == -1)
{
printf("你要修改的人不存在\n");
return;
}
printf("请你输入你要添加的名字:>");
scanf("%s", ps->data[pos].name);
printf("请你输入性别:>");
scanf("%s", ps->data[pos].sex);
printf("请你输入年龄:>");
scanf("%d", &(ps->data[pos].age));
printf("请你输入电话号码:>");
scanf("%s", ps->data[pos].tele);
printf("请你输入地址:>");
scanf("%s", ps->data[pos].addr);
printf("修改成功\n");
}
7. Sort contacts by first name
For sorting here, we use qsort sorting , that is, quick sorting, to sort the names of the contacts.
void cmp_name(void* p1, void* p2)
{
return strcmp(((people*)p1)->name, ((people*)p2)->name);
}
//对联系人名字进行排序
void SortContact(Contact* ps)
{
qsort(ps->data, ps->size, sizeof(people), cmp_name);
}
8. Test sample
3. The complete code of the static address book
1.test.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
void menu()
{
printf("***************************\n");
printf("****** 1.Add 2.Del *****\n");
printf("***** 3.Search 4.Modify ***\n");
printf("***** 5.Show 6.Sort *****\n");
printf("***** 0.Exit *************\n");
printf("***************************\n");
}
enum option
{
Exit,//从0开始,依次往下递增1
Add,
Del,
Search,
Modify,
Show,
Sort
};
int main()
{
int input = 0;
Contact con;
InitContact(&con);
do
{
menu();
printf("请你选择要实现的功能:>\n");
scanf("%d", &input);
switch (input)
{
case Add:
AddContact(&con);
break;
case Del:
DelContact(&con);
break;
case Search:
SearchContact(&con);
break;
case Modify:
ModifyContact(&con);
break;
case Show:
ShowContact(&con);
break;
case Sort:
SortContact(&con);
break;
case Exit:
printf("退出通讯录\n");
break;
}
} while (input);
return 0;
}
2.Contact.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
//初始化通讯录
void InitContact(Contact* ps)
{
ps->size = 0;
memset(ps->data, 0, sizeof(ps->data));
}
//增加联系人
void AddContact(Contact* ps)
{
if (ps->size == MAX)
{
printf("通讯录已经满了,不能添加联系人了\n");
return;
}
printf("请你输入你要添加的名字:>");
scanf("%s", ps->data[ps->size].name);
printf("请你输入性别:>");
scanf("%s", ps->data[ps->size].sex);
printf("请你输入年龄:>");
scanf("%d", &(ps->data[ps->size].age));
printf("请你输入电话号码:>");
scanf("%s", ps->data[ps->size].tele);
printf("请你输入地址:>");
scanf("%s", ps->data[ps->size].addr);
ps->size++;
printf("添加成功\n");
}
//显示联系人
void ShowContact(Contact* ps)
{
int i = 0;
printf("%-10s %-5s %-5s %-12s %-30s\n", "名字", "性别", "年龄", "电话", "地址");
for (i = 0; i < ps ->size; i++)
{
printf("%-10s %-5s %-5d %-12s %-30s\n", ps->data[i].name,
ps->data[i].sex, ps->data[i].age, ps->data[i].tele, ps->data[i].addr);
}
}
//查找联系人
int FindByname(Contact* ps, char name[])
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
if (0==strcmp(name, ps->data[i].name))
{
return i;
}
}
return -1;
}
//删除联系人
void DelContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
if (ps->size == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
printf("请你输入要删除联系人的名字:>");
scanf("%s", name);
int pos = FindByname(ps, name);
if (pos == -1)
{
printf("你要删除的人不存在\n");
return;
}
int i = 0;
for (i = pos; i < ps->size - 1; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->size--;
printf("删除成功\n");
}
//查找联系人
void SearchContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
printf("输入你要查找联系人的名字:>");
scanf("%s", name);
int pos= FindByname(ps, name);
if (pos == -1)
{
printf("你要查找的联系人不存在\n");
return;
}
printf("这是你要查找的人:>\n");
printf("%-10s %-5s %-5s %-12s %-30s\n", "名字", "性别", "年龄", "电话", "地址");
printf("%-10s %-5s %-5d %-12s %-30s\n", ps->data[pos].name,
ps->data[pos].sex, ps->data[pos].age, ps->data[pos].tele, ps->data[pos].addr);
}
//修改联系人
void ModifyContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
printf("输入你要修改联系人的名字\n");
scanf("%s", name);
int pos = FindByname(ps, name);
if (pos == -1)
{
printf("你要修改的人不存在\n");
return;
}
printf("请你输入你要添加的名字:>");
scanf("%s", ps->data[pos].name);
printf("请你输入性别:>");
scanf("%s", ps->data[pos].sex);
printf("请你输入年龄:>");
scanf("%d", &(ps->data[pos].age));
printf("请你输入电话号码:>");
scanf("%s", ps->data[pos].tele);
printf("请你输入地址:>");
scanf("%s", ps->data[pos].addr);
printf("修改成功\n");
}
void cmp_name(void* p1, void* p2)
{
return strcmp(((people*)p1)->name, ((people*)p2)->name);
}
//对联系人名字进行排序
void SortContact(Contact* ps)
{
qsort(ps->data, ps->size, sizeof(people), cmp_name);
int i = 0;
}
3.Contact.h
#pragma once
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 10
//使用结构体存储一个人的信息
typedef struct people
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tele[TELE_MAX];
char addr[ADDR_MAX];
}people;
typedef struct Contact
{
people data[MAX];//存储100个人的信息
int size;
}Contact;
//初始化通讯录
void InitContact(Contact* ps);
//增加联系人
void AddContact(Contact* ps);
//显示联系人
void ShowContact(Contact* ps);
//删除联系人
void DelContact(Contact* ps);
//查找联系人
void SearchContact(Contact* ps);
//修改联系人
void ModifyContact(Contact* ps);
//对联系人名字进行排序
void SortContact(Contact* ps);
4. Optimize the address book
The static address book we wrote above only has a capacity of 100. When we have few contacts , the capacity of 100 is too large, which is a waste of space. When the number of contacts exceeds 100 people , the capacity of the address book is not enough .
So we can optimize the address book and change the static address book to a dynamic address book. Here we use the development of dynamic memory development. If there is not enough space, it will automatically open up space. No space is wasted either .
1. Change the members of the structure to pointers
typedef struct Contact
{
people *data;//创建的动态数组
int size;//存放数据的个数
int Capacity;//动态数组的容量的大小
}Contact;
2. Modify the initialization address book
We use the malloc function to dynamically open up space, and two macro definitions are used here :
#define INC_SZ 2//不够了新开辟2个空间
#define INI_MAX 3//初始化的3个空间
void InitContact(Contact* ps)
{
ps->data = (people*)malloc(sizeof(people) * INI_MAX);
if (ps->data == NULL)
{
printf("初始化通讯录失败:%s", strerror(errno));//打印错误的信息
return;
}
ps->size = 0;
ps->Capacity = INI_MAX;
}
3. Write a capacity-enhancing function
Because when we initialize the address book, the capacity is 3. When we add three contacts, the capacity of the address book will be full, so we need to increase the capacity . The quantity is two.
Here we use the realloc function to open up two more spaces on the basis of the original.
When we want to use the function of adding contacts, just call the capacity increase function at the front of the function.
void CheckCapaticy(Contact* ps)
{
if (ps->size == ps->Capacity)
{
people* ptr = realloc(ps->data, sizeof(people) * (ps->Capacity + INC_SZ));
if (ptr == NULL)
{
printf("CheckCapacity:%s", strerror(errno));
return;
}
else
{
ps->data = ptr;
ps->Capacity += INC_SZ;
printf("增容成功,容量是%s", ps->Capacity);
}
}
}
4. Exit the program and release the memory
Above we used the malloc function and the realloc function, so at the end we have to release the memory.
void DestoryContact(Contact* ps)
{
free(ps->data);
ps->data = NULL;
ps->size = 0;
ps->Capacity = 0;
printf("内存已经销毁……\n");
}
5. The complete code of the optimized version
1.test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
void menu()
{
printf("***************************\n");
printf("****** 1.Add 2.Del *****\n");
printf("***** 3.Search 4.Modify ***\n");
printf("***** 5.Show 6.Sort *****\n");
printf("***** 0.Exit *************\n");
printf("***************************\n");
}
enum option
{
Exit,//从0开始,依次往下递增1
Add,
Del,
Search,
Modify,
Show,
Sort
};
int main()
{
int input = 0;
Contact con;
InitContact(&con);
do
{
menu();
printf("请你选择要实现的功能:>\n");
scanf("%d", &input);
switch (input)
{
case Add:
AddContact(&con);
break;
case Del:
DelContact(&con);
break;
case Search:
SearchContact(&con);
break;
case Modify:
ModifyContact(&con);
break;
case Show:
ShowContact(&con);
break;
case Sort:
SortContact(&con);
break;
case Exit:
DestoryContact(&con);
printf("退出通讯录\n");
break;
}
} while (input);
return 0;
}
2.Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
//初始化通讯录
void InitContact(Contact* ps)
{
ps->data = (people*)malloc(sizeof(people) * INI_MAX);
if (ps->data == NULL)
{
printf("初始化通讯录失败:%s", strerror(errno));
return;
}
ps->size = 0;
ps->Capacity = INI_MAX;
}
//检查容量
void CheckCapaticy(Contact* ps)
{
if (ps->size == ps->Capacity)
{
people* ptr = realloc(ps->data, sizeof(people) * (ps->Capacity + INC_SZ));
if (ptr == NULL)
{
printf("CheckCapacity:%s", strerror(errno));
return;
}
else
{
ps->data = ptr;
ps->Capacity += INC_SZ;
printf("增容成功,容量是%d\n", ps->Capacity);
}
}
}
//增加联系人
void AddContact(Contact* ps)
{
CheckCapaticy(ps);
printf("请你输入你要添加的名字:>");
scanf("%s", ps->data[ps->size].name);
printf("请你输入性别:>");
scanf("%s", ps->data[ps->size].sex);
printf("请你输入年龄:>");
scanf("%d", &(ps->data[ps->size].age));
printf("请你输入电话号码:>");
scanf("%s", ps->data[ps->size].tele);
printf("请你输入地址:>");
scanf("%s", ps->data[ps->size].addr);
ps->size++;
printf("添加成功\n");
}
//显示联系人
void ShowContact(Contact* ps)
{
int i = 0;
printf("%-10s %-5s %-5s %-12s %-30s\n", "名字", "性别", "年龄", "电话", "地址");
for (i = 0; i < ps ->size; i++)
{
printf("%-10s %-5s %-5d %-12s %-30s\n", ps->data[i].name,
ps->data[i].sex, ps->data[i].age, ps->data[i].tele, ps->data[i].addr);
}
}
//查找联系人
int FindByname(Contact* ps, char name[])
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
if (0==strcmp(name, ps->data[i].name))
{
return i;
}
}
return -1;
}
//删除联系人
void DelContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
if (ps->size == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
printf("请你输入要删除联系人的名字:>");
scanf("%s", name);
int pos = FindByname(ps, name);
if (pos == -1)
{
printf("你要删除的人不存在\n");
return;
}
int i = 0;
for (i = pos; i < ps->size - 1; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->size--;
printf("删除成功\n");
}
//查找联系人
void SearchContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
printf("输入你要查找联系人的名字:>");
scanf("%s", name);
int pos= FindByname(ps, name);
if (pos == -1)
{
printf("你要查找的联系人不存在\n");
return;
}
printf("这是你要查找的人:>\n");
printf("%-10s %-5s %-5s %-12s %-30s\n", "名字", "性别", "年龄", "电话", "地址");
printf("%-10s %-5s %-5d %-12s %-30s\n", ps->data[pos].name,
ps->data[pos].sex, ps->data[pos].age, ps->data[pos].tele, ps->data[pos].addr);
}
//修改联系人
void ModifyContact(Contact* ps)
{
char name[NAME_MAX] = { 0 };
printf("输入你要修改联系人的名字\n");
scanf("%s", name);
int pos = FindByname(ps, name);
if (pos == -1)
{
printf("你要修改的人不存在\n");
return;
}
printf("请你输入你要添加的名字:>");
scanf("%s", ps->data[pos].name);
printf("请你输入性别:>");
scanf("%s", ps->data[pos].sex);
printf("请你输入年龄:>");
scanf("%d", &(ps->data[pos].age));
printf("请你输入电话号码:>");
scanf("%s", ps->data[pos].tele);
printf("请你输入地址:>");
scanf("%s", ps->data[pos].addr);
printf("修改成功\n");
}
void cmp_name(void* p1, void* p2)
{
return strcmp(((people*)p1)->name, ((people*)p2)->name);
}
//对联系人名字进行排序
void SortContact(Contact* ps)
{
qsort(ps->data, ps->size, sizeof(people), cmp_name);
}
void DestoryContact(Contact* ps)
{
free(ps->data);
ps->data = NULL;
ps->size = 0;
ps->Capacity = 0;
printf("内存已经销毁……\n");
}
3.Contact.h
#pragma once
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 10
#define INC_SZ 2
#define INI_MAX 3
//使用结构体存储一个人的信息
typedef struct people
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tele[TELE_MAX];
char addr[ADDR_MAX];
}people;
typedef struct Contact
{
people *data;//创建的动态数组
int size;//存放数据的个数
int Capacity;//动态数组的容量的大小
}Contact;
//初始化通讯录
void InitContact(Contact* ps);
//增加联系人
void AddContact(Contact* ps);
//显示联系人
void ShowContact(Contact* ps);
//删除联系人
void DelContact(Contact* ps);
//查找联系人
void SearchContact(Contact* ps);
//修改联系人
void ModifyContact(Contact* ps);
//对联系人名字进行排序
void SortContact(Contact* ps);
//退出程序,销毁内存
void DestoryContact(Contact* ps);