C语言实现通讯录的八种功能(添加、删除、查找、修改、显示、排序、退出、清空)
作者:Chris·Bosh
通讯录功能概要及前提说明
此通讯录利用C语言完成,可以实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)
代码由三部分组成,为什么要写成三部分而不写成一部分可以参考我以前的博客,如下:链接: link
1.通信录具体功能
通讯录可以用来存储100个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
提供方法:
1.添加联系人信息
2.删除指定联系人信息
3.查找指定联系人信息
4.修改指定联系人信息
5.显示所有联系人信息
6.清空所有联系人
7.以名字/年龄/地址排序所有联系人
2.初始化菜单
void menu() { printf("*********************************************\n"); printf("*********************************************\n"); printf("*********************************************\n"); printf("*********1.添加 2.删除*************\n"); printf("*********3.查找 4.修改*************\n"); printf("*********5.显示 6.排序*************\n"); printf("*********7.退出 8.清空*************\n"); printf("*********************************************\n"); printf("*********************************************\n"); printf("*********************************************\n"); }
3.通讯录存储的信息
使用 typedef 将 struct peoinfo 类型自定义成 peoinfo 更加方边后续使用。
利用宏定义设定各个参数的值,后续不需要再重新定义。
#define NAME_MAX 20 #define SEX_MAX 5 #define TELE_MAX 12 #define ADDR_MAX 30 #define MAX 100//最大人数 typedef struct peoinfo { char name[NAME_MAX]; int age; char sex[SEX_MAX]; char tele[TELE_MAX]; char addr[ADDR_MAX]; }peoinfo; typedef struct contact { peoinfo data[MAX]; int sz;//记录当前人的信息个数 }contact;
其中,创建存放联系人的通讯录Contact,存放MAX个联系人对应的信息。sz用于记录当前储存联系人的数量。
4.通讯录基本框架
enum option { add=1, del=2, search=3, modify, show, sort, run, clc }; int main() { int input = 0; contact con;//通讯录 //初始化 initcontact(&con); do { menu(); printf("请输入功能:"); 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 run: printf("退出通讯录\n"); break; case clc: clccontact(&con); break; default: printf("输入非法,请重新输入!\n"); break; } } while (input != 7); return 0; }
我们知道case后只能加整数,为了更加直观的看到每一种功能,我们可以创建枚举类型替换这些整数,枚举类型成员的值从0开始递增1,适用于代替case后的整数,因为我么的菜单选项是从1到8,所以这里我们定义枚举的第一个值为1,这样后面就会默认排序到8。
通讯录运行通过do-while实现,内部调用menu函数打印开始菜单,然后提示用户选择功能。
5.各个部分功能模块声明
void initcontact(contact* pc); void addcontact(contact* pc); void showcontact(contact* pc); void delcontact(contact* pc); void searchcontact(contact* pc); void modifycontact(contact* pc); void sortcontact(contact* pc); void clccontact(contact* pc);
代码的基本框架搭建完毕,我们就要实现每一个选项的功能。这里是定义每一个功能的头文件,声明后才能在别的原文件中使用。
6.初始化模块
void initcontact(contact* pc) { assert(pc); pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); }
给定的代码是一个函数initcontact,它用于初始化一个名为contact的结构体指针pc。以下是对代码的分析:
①函数声明:void initcontact(contact* pc)
声明了一个名为initcontact的函数,它接受一个结构体指针pc作为参数,并且没有返回值(即返回类型为void)。
②断言:assert(pc) 断言确保pc指针不为空。如果pc为空,断言将失败,并导致程序终止。
③初始化:pc->sz = 0 将结构体指针pc的成员变量sz的值设置为0。这意味着将sz用作计数器或存储元素数量的变量。
④内存清零:memset(pc->data, 0, sizeof(pc->data))
使用memset函数将结构体指针pc的成员变量data的内存块清零。sizeof(pc->data)用于确定pc->data成员的大小,以确保清零操作覆盖整个内存块。
⑤通过这些操作,函数initcontact将结构体指针pc所指向的contact结构体进行初始化。初始化的结果是将sz设置为0,并将data的内存块清零。
7.增加联系人模块
void addcontact(contact* pc) { assert(pc); if (pc->sz == MAX) { printf("通讯录已满\n"); return; } //增加信息 printf("请输入名字:"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:"); scanf("%s", pc->data[pc->sz].sex); printf("请输入电话:"); scanf("%s", pc->data[pc->sz].tele); printf("请输入地址:"); scanf("%s", pc->data[pc->sz].addr); pc->sz++; printf("通讯录已添加\n"); Sleep(2000); }
该代码定义了一个名为addcontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后判断通讯录的当前大小是否达到了最大值(MAX),如果达到了最大值则打印提示信息并返回。
③如果通讯录未满,则依次输入联系人的姓名、年龄、性别、电话和地址,并将这些信息保存到通讯录中。
④ 最后,将通讯录的大小加1,并打印添加成功的提示信息。使用Sleep函数暂停程序执行2秒后再弹出菜单继续选择。使使用者方便观察。
8.显示通讯录模块
void showcontact(contact* pc) { assert(pc); if (pc->sz == 0) { printf("通讯录为空\n"); return; } int i = 0; printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); } Sleep(2000); }
该代码定义了一个名为showcontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后判断通讯录的大小是否为0,如果为0则打印提示信息并返回。
③接下来,使用一个循环遍历通讯录中的每个联系人,并依次打印其姓名、年龄、性别、电话和地址。
④ 最后,使用Sleep函数暂停程序执行2秒。
需要注意的是,该代码依赖于一些未给出的头文件和结构体定义,例如contact结构体的定义。另外,该代码使用了格式化输出函数printf,其中使用了%-10s、%-5d等格式控制符,用于设置输出字段的宽度和对齐方式。
9.删除用户模块
int findname(contact* pc, char name[]) { assert(pc); int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return 1; } } return -1; } void delcontact(contact* pc) { char name[NAME_MAX]; assert(pc); if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } printf("输入要删除人的名字:"); scanf("%s", name); int ret = findname(pc,name); if (ret == -1) { printf("要删除的人不存在\n"); return; } int i = 0; for (i = ret; i <pc->sz-1 ; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); Sleep(2000); }
该代码定义了两个函数:findname和delcontact。
findname函数用于在通讯录中查找指定姓名的联系人,函数参数为一个指向contact结构体的指针pc和一个字符数组name。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后使用一个循环遍历通讯录中的每个联系人,通过strcmp函数比较联系人的姓名是否与指定的name相等。如果相等,则返回1表示找到了该联系人。
③如果遍历完整个通讯录都没有找到匹配的姓名,则返回-1表示未找到。
④delcontact函数用于从通讯录中删除指定姓名的联系人,函数参数为一个指向contact结构体的指针pc。
⑤函数首先使用assert函数进行断言,确保指针pc不为空。
⑥然后判断通讯录的大小是否为0,如果为0则打印提示信息并返回。
⑦接下来,依次输入要删除的联系人的姓名,并调用findname函数查找该联系人是否存在。如果不存在,则打印提示信息并返回。
⑧如果存在,使用一个循环从找到的位置开始,将后面的联系人逐个往前移动一位,实现删除该联系人的功能。
⑨最后,将通讯录的大小减1,并打印删除成功的提示信息。使用Sleep函数暂停程序执行2秒。
10.查找用户模块
void searchcontact(contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要查找人的姓名:"); scanf("%s", name); int ret = findname(pc, name); if (ret == -1) { printf("要查找的人不存在\n"); return; } printf("查询成功!!\n"); printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr); Sleep(2000); }
该代码定义了一个名为searchcontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后输入要查找的联系人的姓名。
③接下来,调用findname函数查找该姓名的联系人在通讯录中的位置。如果返回值为-1,则打印提示信息并返回。
④如果返回值不为-1,表示找到了该联系人,打印查询成功的提示信息。
⑤然后,使用printf函数按照一定的格式打印该联系人的姓名、年龄、性别、电话和地址。
⑥最后,使用Sleep函数暂停程序执行2秒。
11.修改用户信息模块
void modifycontact(contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要查找人的姓名:"); scanf("%s", name); int ret = findname(pc, name); if (ret == -1) { printf("要修改的人不存在\n"); return; } printf("请输入名字:"); scanf("%s", pc->data[ret].name); printf("请输入年龄:"); scanf("%d", &(pc->data[ret].age)); printf("请输入性别:"); scanf("%s", pc->data[ret].sex); printf("请输入电话:"); scanf("%s", pc->data[ret].tele); printf("请输入地址:"); scanf("%s", pc->data[ret].addr); printf("修改成功!\n"); }
该代码定义了一个名为modifycontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后输入要修改的联系人的姓名。
③接下来,调用findname函数查找该姓名的联系人在通讯录中的位置。如果返回值为-1,则打印提示信息并返回。
④如果返回值不为-1,表示找到了该联系人,依次输入要修改的联系人的姓名、年龄、性别、电话和地址,并将这些信息更新到通讯录中。
⑤最后,打印修改成功的提示信息。
12.排序用户信息模块
int cmp_name(const void* p1, const void* p2) { return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name); } int cmp_age(const void* p1, const void* p2) { return ((peoinfo*)p1)->age-((peoinfo*)p2)->age; } int cmp_addr(const void* p1, const void* p2) { return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr); } void sortcontact(contact* pc) { int i = 0; char sort_choose[10]; char sort_choose1[] = "name"; char sort_choose2[] = "age"; char sort_choose3[] = "addr"; A: printf("请输入根据什么进行排序:"); scanf("%s", sort_choose); if (strcmp(sort_choose,sort_choose1) == 0) { //利用qsort 函数 qsort(pc->data, pc->sz, sizeof((pc->data)[0]), cmp_name); } else if (strcmp(sort_choose,sort_choose2) == 0) { qsort(pc->data, pc->sz, sizeof((pc->data)[1]), cmp_age); } else if (strcmp(sort_choose,sort_choose3) == 0) { qsort(pc->data, pc->sz, sizeof((pc->data)[4]), cmp_addr); } else { printf("无此排序参数,请重新输入参数\n"); goto A; } //打印列标题 printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址"); //打印数据 for (i = 0; i < pc->sz; i++) { printf("%-10s%-5d%-5s%-12s%-30s\t\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); } Sleep(2000); }
该代码定义了三个比较函数:cmp_name、cmp_age和cmp_addr。这些函数用于在排序通讯录时比较联系人信息的不同字段。
①cmp_name函数用于比较联系人姓名的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过调用strcmp函数比较两个联系人的姓名,并返回比较结果。
② cmp_age函数用于比较联系人年龄的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过将第一个联系人的年龄减去第二个联系人的年龄,并返回比较结果。
③cmp_addr函数用于比较联系人地址的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过调用strcmp函数比较两个联系人的地址,并返回比较结果。
④sortcontact函数用于对通讯录中的联系人进行排序,函数参数为一个指向contact结构体的指针pc。
⑤函数首先定义一些变量和字符串数组用于接收用户输入的排序参数。
⑥然后,通过标签A实现一个循环,提示用户输入根据什么进行排序。根据用户的输入,分别调用qsort函数进行排序。排序时,根据用户的选择调用不同的比较函数。
⑦如果用户输入的排序参数无效,则打印提示信息并跳转回标签A,要求用户重新输入。
⑧排序完成后,先打印列标题,然后依次打印排序后的联系人信息。
⑨最后,使用Sleep函数暂停程序执行2秒。
13.清除模块
void clccontact(contact* pc) { pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); printf("通讯录已经清空!!!\n"); Sleep(2000); }
此代码实现了一个清空通讯录的函数。(即和初始化模块一样)函数接收一个指向联系人结构体的指针,将通讯录结构体中的数据清空,包括sz(通讯录中已有联系人数量)和data(存放联系人信息的数组)。最后输出提示信息“通讯录已经清空!!!”并延时2秒。
此代码的功能比较简单,只是清空通讯录。可以作为通讯录管理系统的一个基本操作函数之一。
14.完整源代码
test.c如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include "adressbook.h" void menu() { printf("*********************************************\n"); printf("*********************************************\n"); printf("*********************************************\n"); printf("*********1.添加 2.删除*************\n"); printf("*********3.查找 4.修改*************\n"); printf("*********5.显示 6.排序*************\n"); printf("*********7.退出 8.清空*************\n"); printf("*********************************************\n"); printf("*********************************************\n"); printf("*********************************************\n"); } enum option { add=1, del=2, search=3, modify, show, sort, run, clc }; int main() { int input = 0; contact con;//通讯录 //初始化 initcontact(&con); do { menu(); printf("请输入功能:"); 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 run: printf("退出通讯录\n"); break; case clc: clccontact(&con); break; default: printf("输入非法,请重新输入!\n"); break; } } while (input != 7); return 0; }
addressbook.c如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include "adressbook.h" void initcontact(contact* pc) { assert(pc); pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); } void addcontact(contact* pc) { assert(pc); if (pc->sz == MAX) { printf("通讯录已满\n"); return; } //增加信息 printf("请输入名字:"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:"); scanf("%s", pc->data[pc->sz].sex); printf("请输入电话:"); scanf("%s", pc->data[pc->sz].tele); printf("请输入地址:"); scanf("%s", pc->data[pc->sz].addr); pc->sz++; printf("通讯录已添加\n"); Sleep(2000); } void showcontact(contact* pc) { assert(pc); if (pc->sz == 0) { printf("通讯录为空\n"); return; } int i = 0; printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); } Sleep(2000); } int findname(contact* pc, char name[]) { assert(pc); int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return 1; } } return -1; } void delcontact(contact* pc) { char name[NAME_MAX]; assert(pc); if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } printf("输入要删除人的名字:"); scanf("%s", name); int ret = findname(pc,name); if (ret == -1) { printf("要删除的人不存在\n"); return; } int i = 0; for (i = ret; i <pc->sz-1 ; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); Sleep(2000); } void searchcontact(contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要查找人的姓名:"); scanf("%s", name); int ret = findname(pc, name); if (ret == -1) { printf("要查找的人不存在\n"); return; } printf("查询成功!!\n"); printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr); Sleep(2000); } void modifycontact(contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要查找人的姓名:"); scanf("%s", name); int ret = findname(pc, name); if (ret == -1) { printf("要修改的人不存在\n"); return; } printf("请输入名字:"); scanf("%s", pc->data[ret].name); printf("请输入年龄:"); scanf("%d", &(pc->data[ret].age)); printf("请输入性别:"); scanf("%s", pc->data[ret].sex); printf("请输入电话:"); scanf("%s", pc->data[ret].tele); printf("请输入地址:"); scanf("%s", pc->data[ret].addr); printf("修改成功!\n"); } int cmp_name(const void* p1, const void* p2) { return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name); } int cmp_age(const void* p1, const void* p2) { return ((peoinfo*)p1)->age-((peoinfo*)p2)->age; } int cmp_addr(const void* p1, const void* p2) { return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr); } void sortcontact(contact* pc) { int i = 0; char sort_choose[10]; char sort_choose1[] = "name"; char sort_choose2[] = "age"; char sort_choose3[] = "addr"; A: printf("请输入根据什么进行排序:"); scanf("%s", sort_choose); if (strcmp(sort_choose,sort_choose1) == 0) { //利用qsort 函数 qsort(pc->data, pc->sz, sizeof((pc->data)[0]), cmp_name); } else if (strcmp(sort_choose,sort_choose2) == 0) { qsort(pc->data, pc->sz, sizeof((pc->data)[1]), cmp_age); } else if (strcmp(sort_choose,sort_choose3) == 0) { qsort(pc->data, pc->sz, sizeof((pc->data)[4]), cmp_addr); } else { printf("无此排序参数,请重新输入参数\n"); goto A; } //打印列标题 printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址"); //打印数据 for (i = 0; i < pc->sz; i++) { printf("%-10s%-5d%-5s%-12s%-30s\t\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); } Sleep(2000); } void clccontact(contact* pc) { pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); printf("通讯录已经清空!!!\n"); Sleep(2000); }
addressbook.h如下:
#define _CRT_SECURE_NO_WARNINGS 1 #define NAME_MAX 20 #define SEX_MAX 5 #define TELE_MAX 12 #define ADDR_MAX 30 #define MAX 100 #include <stdio.h> #include <assert.h> #include <string.h> #include <Windows.h> typedef struct peoinfo { char name[NAME_MAX]; int age; char sex[SEX_MAX]; char tele[TELE_MAX]; char addr[ADDR_MAX]; }peoinfo; typedef struct contact { peoinfo data[MAX]; int sz;//记录当前人的信息个数 }contact; void initcontact(contact* pc); void addcontact(contact* pc); void showcontact(contact* pc); void delcontact(contact* pc); void searchcontact(contact* pc); void modifycontact(contact* pc); void sortcontact(contact* pc); void clccontact(contact* pc);
大家只需要将此代码,按照文章开头设置为三部分,点击运行即可。
到此这篇关于C语言实现通讯录的八种功能(添加、删除、查找、修改、显示、排序、退出、清空)的文章就介绍到这了,更多相关C语言 通讯录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!