普通版
需求
通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
提供方法:
添加联系人信息
删除指定联系人信息
查找指定联系人信息
修改指定联系人信息
显示所有联系人信息
清空所有联系人
以名字排序所有联系人
模块设计
test.c 测试通讯录 contact.h 函数和类型的声明 contact.c 函数的实现
test.c模块实现
int main() { test(); return 0; }
然后我们在实现test函数时,我们需要完成通讯录的显示菜单,还需要操作者可以进行选择
首先要制作一个菜单
并将每个选项的功能纳入菜单的选项中
#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("******** 7.init 0.exit ********\n"); printf("***********************************\n"); } void test() { 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 FINIT: Finitcontact(&con); break; case EXIT: printf("退出通讯录\n"); break; default: printf("重新选择\n"); break; } } while (input); } int main() { test(); return 0; }
而在此处出现的结构体contact与枚举会在contact.h模块进行声明,还有函数Initcontact声明也会在contact.h说明,具体实现会在contact.c模块进行实现
contact.h模块实现
类型的声明
//定义 typedef struct PeoInfo { char name[100]; int age; char sex[5]; char tele[20]; char addr[30]; }PeoInfo; //信息初始化 typedef struct contact { PeoInfo data[100]; int sz; }contact;
sz存在的意义为可以知道通讯录里有多少联系人
函数的声明
//初始化 void Initcontact(contact *); //添加信息 void Addcontact(contact *); //展示信息 void Showcontact(const contact *); //删除信息 void Delcontact(contact*); //查找信息 int Findcontact(const contact*,char); //查找联系人 void Searchcontact(const contact*); //修改信息 void Modifyconduct(contact*); //排序所有信息 void Sortcontact(contact* pc); //清空信息 void Finitcontact(contact*);
头文件和宏定义
#pragma once #include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #define MAX 1000 #define MAX_name 20 #define MAX_sex 5 #define MAX_tele 20 #define MAX_addr 30
为了让使用者更加方便
我们用枚举将switch语句中的选项改变成文字
enum Option { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT, FINIT };
contact.c 模块实现
通讯录初始化
//初始化 void Initcontact(contact* pc) { memset(pc->data, 0, sizeof(pc->data)); pc->sz = 0; }
增加联系人
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"); }
删除联系人
void Delcontact(contact* pc) { if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } char name[MAX_name] = { 0 }; assert(pc); printf("请输入要删除的人的名字\n"); scanf("%s", &name); int del = Findcontact(pc, name); if (del == -1) { printf("不存在要删除的人\n"); return; } //移动方法一 int i=0; for (i = del; i < pc->sz; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("成功删除联系人\n"); }
这里的Findcontact是一个特殊的方法
//查找信息(通过名字找) static int Findcontact(const contact* pc,char name[]) { int i = 0; int del = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return i; } } return -1; }
而这里的删除实际是通过覆盖的方式来实现
查找联系人
void Searchcontact(const contact* pc) { char name[MAX_name]; printf("请输入要查找的名字\n"); scanf("%s",name); int pos = Findcontact; if (pos == -1) { printf("不存在要查找的人\n"); return; } else { printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr); } }
修改联系人信息
void Modifycontact(contact* pc) { char name[MAX_name] = { 0 }; assert(pc); printf("请输入要修改的人的名字\n"); scanf("%s", &name); int pos = Findcontact(pc, name); if (pos == -1) { printf("不存在要修改的人\n"); return; } else { printf("请输入名字:>"); scanf("%s", pc->data[pos].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pos].age)); printf("请输入性别:>"); scanf("%s", pc->data[pos].sex); printf("请输入电话:>"); scanf("%s", pc->data[pos].tele); printf("请输入地址:>"); scanf("%s", pc->data[pos].addr); printf("修改成功\n"); } }
展示所有联系人信息
void Showcontact(const contact* pc) { int i = 0; printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); } }
按名字排序
static int cmp_by_name(const void* e1, const void* e2) { return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name); } static void swap(char* buf1, char* buf2, size_t width) { unsigned int i = 0; for (i = 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++; buf2++; } } static void my_bubble_sort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2)) { unsigned int i = 0; unsigned int j = 0; for (i = 0; i < num - 1; i++) { for (j = 0; j < num - 1 - i; j++) { if (cmp_by_name((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { swap(((char*)base + j * width), ((char*)base + (j + 1) * width), width); } } } } void Sortcontact(contact* pc) { my_bubble_sort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name); printf("排序成功\n"); }
清空联系人信息
void Finitcontact(contact* pc) { memset(pc->data, 0, sizeof(pc->data)); pc->sz = 0; printf("清空成功\n"); }
动态版
模块一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("******** 7.init 0.exit ********\n"); printf("***********************************\n"); } void test() { 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 FINIT: Finitcontact(&con); break; case EXIT: Destroycontact(&con); printf("退出通讯录\n"); break; default: printf("重新选择\n"); break; } } while (input); } int main() { test(); return 0; }