目标:通讯录可以存放1000个人信息,人的信息:性别名字年龄电话住址 菜单打印
1.增加联系人
2.删除联系人
3.查找联系人(修改)
4.名字排序联系人
5.展示
6.清空
分析:
首先通讯录存放联系人信息,还需知晓联系人个数,因此是个结构体类型
其次人的信息类型多,因此每个联系人也应为结构体类型
说明:
每个标题下展示的代码顺序:test.c (主函数测试运行) -> contact.h (功能函数声明) -> contact.c (功能函数实现)
菜单打印:
void menu() { printf("***************************\n"); printf("*** 1.add 2.del ***\n"); printf("*** 3.serch (modify) ***\n"); printf("*** 4.sort 5.show ***\n"); printf("*** 0.exit 6.clear ***\n"); printf("***************************\n"); } int main() { int input = 0; do { menu(); printf("请选择->"); scanf("%d",&input); switch (input) { case 1: //增加信息 break; case 2: //删除 break; case 3: //查找(修改) break; case 4: //按名字排序 break; case 5: //显示联系人信息 break; case 6: //清空联系人 break; case 0: //退出通讯录 break; dafault: break; } } while (input); }
枚举优化:
上述菜单可以用枚举对代码可读性进行优化,改进如下:
enum Oprion { Exit, Add, Del, Serch, Sort, Show, Clear }; void menu() { printf("***************************\n"); printf("*** 1.add 2.del ***\n"); printf("*** 3.serch (modify) ***\n"); printf("*** 4.sort 5.show ***\n"); printf("*** 0.exit 6.clear ***\n"); printf("***************************\n"); } int main() { int input = 0; do { menu(); printf("请选择->"); scanf("%d",&input); switch (input) { case Add: //增加信息 break; case Del: //删除 break; case Serch: //查找(修改) break; case Sort: //按名字排序 break; case Show: //显示联系人信息 break; case Clear: //清空联系人 break; case Exit: //退出通讯录 break; dafault: break; } } while (input); }
定义结构体
#define Max 1000 #define name_Max 20 #define sex_Max 5 #define addr_Max 30 #define phone_Max 12 //结构体人的信息 typedef struct Peoinfo { char name[name_Max]; int age; char sex[sex_Max]; char addr[addr_Max]; char phone[phone_Max]; }Peoinfo; //结构体通讯录的信息 typedef struct Contact { Peoinfo data[1000]; //存放数据 int sz; //通讯录中有效信息的个数(里面有几个人) }Contact;
初始化
//完善菜单主函数部分 int main() { int input = 0; Contact con;//通讯录 InitContact(&con);//初始化通讯录 do
//初始化通讯录 void InitContact(Contact* pc); //初始化通讯录 void InitContact(Contact* pc) { assert(pc); pc->sz = 0; memset(pc->data,0,sizeof(pc->data)); //将数组初始化为0 }
增加信息
case Add: //增加信息 AddContact(&con); break; //增加信息到通讯录 void AddContact(Contact* pc); //增加信息 void AddContact(Contact* pc) { assert(pc); if (pc->sz==Max) { printf("通讯录满了,无法添加\n"); return 0; } //输入信息 printf("请输入名字:"); scanf("%s",pc->data[pc->sz].name); //增加的信息应该在原有效信息位置后,用pc->sz指向对应位置 printf("请输入年龄:"); scanf("%d", &(pc->data[pc->sz].age)); //age是个变量,注意需要取地址 printf("请输入性别:"); scanf("%s", pc->data[pc->sz].sex); printf("请输入地址:"); scanf("%s", pc->data[pc->sz].addr); printf("请输入电话:"); scanf("%s", pc->data[pc->sz].phone); pc->sz++; //元素个数加一 printf("添加成功\n"); }
这里要注意通讯录已满的情况,并且添加信息时要注意是在原有效信息后得地址开始添加,防止重复。
删除信息
case Del: //删除 DeletContact(&con); break; //删除 void DeletContact(Contact* pc); int FindByname(Contact*pc, char name[]) { int i = 0; for (i = 0;isz;i++) { if (strcmp(pc->data[i].name, name)==0) { return i; } } printf("没找到\n"); return -1; } //删除信息 void DeletContact(Contact* pc) { char name[name_Max]; if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); } printf("请输入要删除人的名字:"); scanf("%s",name); //实现查找函数 int pos=FindByname(pc,name); //若找到返回下标,找不到则返回-1 if (pos==-1) { printf("无此人\n"); } else { //删除--要删除元素后面的元素依次向前覆盖 int j = 0; for (j = pos;j sz-1;j++) { pc->data[j] = pc->data[j + 1]; } pc->sz--; printf("删除成功\n"); } }
这里要注意一个查找函数,输入名字来查找联系人,找到才能删除。
查找(修改)
case Serch: printf("请输入要查找人的名字:"); scanf("%s", name); FindByname(&con,name); break; //查找 int FindByname(const Contact*pc, char name[]); int FindByname(Contact*pc, char name[]) { int i = 0; for (i = 0;isz;i++) { if (strcmp(pc->data[i].name, name)==0) { int put = 0; printf("%-10s\t%-5d\t%-5s\t%-15s\t%-20s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].phone); //找到后可以将内容展现出来 printf("找着了\n请选择是否修改:1.是 0.否\n"); scanf("%d",&put); if (1 == put) { Modify(pc->data,i); } return i; } } printf("没找到\n"); return -1; }
这里我将第二项删除功能的查找函数进行声明使用,并且将修改函数加入到查找函数中,两个功能联合到一起,但是在使用删除功能的时候会出现重复,这里要注意。
修改函数如下:
//修改 void Modify(Contact* pc,int i) { int bud = 0; do { printf("请选择需要修改的内容\n1.名字 2.年龄 3.性别 4.地址 5.电话 0.取消\n请输入:"); scanf("%d", &bud); switch (bud) { char chars[30] = { 0 }; case 1: { printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].name , chars); } break; case 2: { int num = 0; printf("请输入内容->"); scanf("%d", &num); pc->data[i].age = num; } break; case 3: { printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].sex , chars); } break; case 4: printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].addr , chars); break; case 5: { printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].phone , chars); } break; dafault: break; } } while (bud); }
修改用到了字符串函数strcpy
名字排序
case Sort: Sortname(&con); break; //名字排序 void Sortname(Contact* pc); //name排序 int cmp_int(const void*e1,const void*e2) { return (strcmp(((Peoinfo*)e1)->name, ((Peoinfo*)e2)->name)); } void Sortname(Contact* pc) { qsort(pc->data,pc->sz,sizeof(pc->data[0]),cmp_int); ShowContact(pc); }
按名字排序这里,我用到了快速排序qsort函数来进行。排序后调用展示函数进行打印,来观察排序效果。
展示信息
case Show: //显示 ShowContact(&con); break; //展示信息 void ShowContact(const Contact* pc); //展示信息 void ShowContact(const Contact* pc) { assert(pc); int i = 0; for (i = 0;i < pc->sz;i++) { printf("%-10s\t%-5d\t%-5s\t%-15s\t%-20s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].phone); //加负号左对齐,加/t统一每个元素间的距离 } }
清空联系人
case Clear: ClearContact(&con); break; //清空所有联系人 void ClearContact(Contact* pc); //清空所有联系人 void ClearContact(Contact* pc) { InitContact(pc); }
清空联系人,相当于再进行一遍初始化通讯录。
头文件统一在contact.h里面包含:
#include#include #include #include
test.c 和 contact.c 统一引用头文件 contact.h
#include "contact.h"
总程序如下
test.c
#include "contact.h" enum Oprion { Exit, Add, Del, Serch, Sort, Show, Clear }; void menu() { printf("***************************\n"); printf("*** 1.add 2.del ***\n"); printf("*** 3.serch (modify) ***\n"); printf("*** 4.sort 5.show ***\n"); printf("*** 0.exit 6.clear ***\n"); printf("***************************\n"); } int main() { int input = 0; Contact con;//通讯录 InitContact(&con);//初始化通讯录 do { char name[name_Max]; menu(); printf("请选择->"); scanf("%d",&input); switch (input) { case Add: //增加信息 AddContact(&con); break; case Del: //删除 DeletContact(&con); break; case Serch: printf("请输入要查找人的名字:"); scanf("%s", name); FindByname(&con,name); break; //case 4: // //修改 // Modify(&con); // break; case Sort: Sortname(&con); break; case Show: //显示 ShowContact(&con); break; case Clear: ClearContact(&con); break; case Exit: printf("退出通讯录\n"); break; dafault: break; } } while (input); }
contact.h
//声明 #include#include #include #include #define Max 1000 #define name_Max 20 #define sex_Max 5 #define addr_Max 30 #define phone_Max 12 //结构体人的信息 typedef struct Peoinfo { char name[name_Max]; int age; char sex[sex_Max]; char addr[addr_Max]; char phone[phone_Max]; }Peoinfo; //结构体通讯录的信息 typedef struct Contact { Peoinfo data[1000]; //存放数据 int sz; //通讯录中有效信息的个数(里面有几个人) }Contact; //初始化通讯录 void InitContact(Contact* pc); //增加信息到通讯录 void AddContact(Contact* pc); //展示信息 void ShowContact(const Contact* pc); //删除 void DeletContact(Contact* pc); //查找 int FindByname(const Contact*pc, char name[]); //名字排序 void Sortname(Contact* pc); //修改 void Modify(Contact* pc, int i); //清空所有联系人 void ClearContact(Contact* pc);
contact.c
#include "contact.h" //初始化通讯录 void InitContact(Contact* pc) { assert(pc); pc->sz = 0; memset(pc->data,0,sizeof(pc->data)); //将数组初始化为0 } //增加信息 void AddContact(Contact* pc) { assert(pc); if (pc->sz==Max) { printf("通讯录满了,无法添加\n"); return 0; } //输入信息 printf("请输入名字:"); scanf("%s",pc->data[pc->sz].name); //增加的信息应该在原有效信息位置后,用pc->sz指向对应位置 printf("请输入年龄:"); scanf("%d", &(pc->data[pc->sz].age)); //age是个变量,注意需要取地址 printf("请输入性别:"); scanf("%s", pc->data[pc->sz].sex); printf("请输入地址:"); scanf("%s", pc->data[pc->sz].addr); printf("请输入电话:"); scanf("%s", pc->data[pc->sz].phone); pc->sz++; //元素个数加一 printf("添加成功\n"); } //展示信息 void ShowContact(const Contact* pc) { assert(pc); int i = 0; for (i = 0;i < pc->sz;i++) { printf("%-10s\t%-5d\t%-5s\t%-15s\t%-20s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].phone); //加负号左对齐,加/t统一每个元素间的距离 } } int FindByname(Contact*pc, char name[]) { int i = 0; for (i = 0;isz;i++) { if (strcmp(pc->data[i].name, name)==0) { int put = 0; printf("%-10s\t%-5d\t%-5s\t%-15s\t%-20s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].phone); printf("找着了\n请选择是否修改:1.是 0.否\n"); scanf("%d",&put); if (1 == put) { Modify(pc->data,i); } return i; } } printf("没找到\n"); return -1; } //删除信息 void DeletContact(Contact* pc) { char name[name_Max]; if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); } printf("请输入要删除人的名字:"); scanf("%s",name); //实现查找函数 int pos=FindByname(pc,name); //若找到返回下标,找不到则返回-1 if (pos==-1) { printf("无此人\n"); } else { //删除--要删除元素后面的元素依次向前覆盖 int j = 0; for (j = pos;j sz-1;j++) { pc->data[j] = pc->data[j + 1]; } pc->sz--; printf("删除成功\n"); } } //name排序 int cmp_int(const void*e1,const void*e2) { return (strcmp(((Peoinfo*)e1)->name, ((Peoinfo*)e2)->name)); } void Sortname(Contact* pc) { qsort(pc->data,pc->sz,sizeof(pc->data[0]),cmp_int); ShowContact(pc); } //修改 void Modify(Contact* pc,int i) { int bud = 0; do { printf("请选择需要修改的内容\n1.名字 2.年龄 3.性别 4.地址 5.电话 0.取消\n请输入:"); scanf("%d", &bud); switch (bud) { char chars[30] = { 0 }; case 1: { printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].name , chars); } break; case 2: { int num = 0; printf("请输入内容->"); scanf("%d", &num); pc->data[i].age = num; } break; case 3: { printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].sex , chars); } break; case 4: printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].addr , chars); break; case 5: { printf("请输入内容->"); scanf("%s", chars); strcpy(pc->data[i].phone , chars); } break; dafault: break; } } while (bud); } //清空所有联系人 void ClearContact(Contact* pc) { InitContact(pc); }
到此这篇关于C语言实现简易通讯录完整流程的文章就介绍到这了,更多相关C语言 简易通讯录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!