简易通讯录
今天,我们来写一手通讯录。
首先我们既然要写一个通讯录,最起码这个通讯录能实现一些简易的功能。比如:增加联系人,删除联系人,查找联系人,修改联系人等等。其中也运用了一些简单的结构体知识以及简单的C语言知识。
当我们想创建一个通讯录的时候,一个界面肯定是少不了的。
因此,我们首先搞一手界面。
代码如下:
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");
}
细心的同学可能发现了,我们使用一手函数,当然,在我们进行这些简易而又内容的稍多的内容时,分装一个函数是极好的。
其次,既然要实现通讯录的功能,那么通讯录中人的信息肯定是必不可少的,其中要包括:姓名,性别,年龄,电话,地址等等。
那么,为了在引用这些数据时能够方便引用,我们可以将这些内容写进一个结构体中。
代码如下:
struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
};
为了使用这些变量时,想修改的时候能便利一些,这里我运用了全局变量进行定义。
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
这样的话,如果我想修改他们的大小,只要修改全局变量里面的就可以了。
我们既然已经定义了一个结构体来描述一个人的基本信息,那么肯定需要定义一个结构体来能存放通讯录的人。定义代码如下:
struct Contact
{struct PeoInfo data[MAX];//PeoInfo 是数组的类型 data是数组名//1000个人的数据存放在data数组中 因为PeoInfo中包含一个人的全部信息//所以直接使用PeoInfo这个结构体名字来定义一个结构体数组int sz;//记录当前通讯录有效信息的个数
};
具体初始化代码如下:
void InitContact(struct Contact* pc)
{pc->sz = 0;memset(pc->data, 0, MAX * sizeof(struct PeoInfo));//memset(pc->data,0,sizeof(pc->data)); 等值于上式//memset设置内存memset(设置的对象,设置的值,设置的空间大小)
}
那么这个通讯录的基本初始化已经完成了。如果我们存入数据后,还想继续存入数据也就是重复进行这一通讯录,这不禁使我们想起了do while函数。再通过switch函数将界面的各个操作给实现一下,综上所述,可得下边的代码:
int main(){int input = 0;//创建一个通讯录/* struct是定义结构体的关键字Contact是结构体的名字con是结构体变量在C语言 如果要创建结构体变量 必须在结构体名字前加struct也就是 struct Contact 这个相当于是一个新的类型 和int之类的类似*/struct Contact con;//定义结构体变量//初始化通讯录InitContact(&con);//将con的地址传给InitContact函数 以此来进行初始化condo{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 EXIT:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);}
由case后边的数值我们可使用枚举类型将这些变量给以此定义一下。代码如下:
enum Option//枚举类型
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
接下来的操作就比较简单了,分别实现增删查改的各个结构体的功能。
增加联系人代码如下:
void AddContact(struct Contact* pc)
{if (pc->sz == MAX){printf("通讯录满了\n");}else{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);printf("添加成功\n");pc->sz++;}
}
当我们实现增加联系人的时候并不需要知道联系人当前通讯录中人的具体信息,但是在实现删除,查看,修改的时候,前提是必须进行判断,判断通讯录中是否有此人的信息,因此我们需要一个结构体函数来实现在当前通讯录中进行查找,并检查是否有此人。
代码如下:
int FindContactByName(const struct Contact* pc, const char* name)
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0)return i;}return -1;}
由上述函数可知,当有此人是返回此人对应的位置。若没有此人,将返回-1;
所以,无论是删除还是查看还是修改,前提都需要进行这一步。
接下来,删除联系人代码如下:
void DelContact(struct Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}char name[NAME_MAX] = { 0 };printf("请输入要删除人的名字:>");scanf("%s", name);//name为数组名//查找int pos= FindContactByName(pc, name);//删除if (pos == -1){printf("指定的联系人不存在");}else{int j = 0;for (j = pos; j <pc->sz-1 ; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("删除成功\n");}
}
寻找联系人,并且打印他的相关信息代码如下:
void SearchContact(const struct Contact*pc)
{char name[NAME_MAX] = { 0 };printf("输入要查找人的名字:>");scanf("%s", name);int pos = FindContactByName(pc, name);if (-1 == pos){printf("查无此人\n");}else{printf("%15s\t%5s\t%8s\t%15s\t%30s\n", "name", "age", "sex", "tele", "addr");printf("%15s\t%5d\t%8s\t%15s\t%30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);}
}
展示当前通讯录中联系人代码如下:
void ShowContact(struct Contact* pc)
{int i = 0;printf("%15s\t%5s\t%8s\t%15s\t%30s\n", "name", "age", "sex", "tele", "addr");for (i = 0; i < pc->sz; i++){//打印每一个数据printf("%15s\t%5d\t%8s\t%15s\t%30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}
}
修改联系人代码如下:
void ModifyContact(struct Contact* pc)
{char name[NAME_MAX] = { 0 };printf("输入要修改人的名字:>");scanf("%s", name);int pos = FindContactByName(pc, name);if (-1 == pos){printf("要修改的人不存在\n");}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);}}
那么这些细节性的东西基本已经完毕,为了使这个通讯录更为容易理解,我们将这些代码进行了分类。
主体放在test.c中
代码如下:
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>
#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,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};int main(){int input = 0;//创建一个通讯录/* struct是定义结构体的关键字Contact是结构体的名字con是结构体变量在C语言 如果要创建结构体变量 必须在结构体名字前加struct也就是 struct Contact 这个相当于是一个新的类型 和int之类的类似*/struct Contact con;//定义结构体变量//初始化通讯录InitContact(&con);//将con的地址传给InitContact函数 以此来进行初始化condo{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 EXIT:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);}
定义的结构体函数放在contact.h中,代码如下:
#pragma once#include<string.h>
//为了以后修改变量的简便从而创建了全局变量
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 1000
//描述单个人的信息
struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
};
struct Contact
{struct PeoInfo data[MAX];//PeoInfo 是数组的类型 data是数组名//1000个人的数据存放在data数组中 因为PeoInfo中包含一个人的全部信息//所以直接使用PeoInfo这个结构体名字来定义一个结构体数组int sz;//记录当前通讯录有效信息的个数
};
//初始化通讯录
void InitContact(struct Contact* pc);//增加联系人
void AddContact(struct Contact* pc);//显示联系人
void ShowContact(struct Contact* pc);//删除指定联系人
void DelContact(struct Contact* pc);//查找指定联系人
void SearchContact(const struct Contact* pc);//修改指定联系人
具体的增删查改等的结构体函数放在contact.c中,具体的代码如下:
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS#include"contact.h"void InitContact(struct Contact* pc)
{pc->sz = 0;memset(pc->data, 0, MAX * sizeof(struct PeoInfo));//memset(pc->data,0,sizeof(pc->data)); 等值于上式//memset设置内存memset(设置的对象,设置的值,设置的空间大小)
}
void AddContact(struct Contact* pc)
{if (pc->sz == MAX){printf("通讯录满了\n");}else{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);printf("添加成功\n");pc->sz++;}
}
void ShowContact(struct Contact* pc)
{int i = 0;printf("%15s\t%5s\t%8s\t%15s\t%30s\n", "name", "age", "sex", "tele", "addr");for (i = 0; i < pc->sz; i++){//打印每一个数据printf("%15s\t%5d\t%8s\t%15s\t%30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}
}
int FindContactByName(const struct Contact* pc, const char* name)
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0)return i;}return -1;}
void DelContact(struct Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}char name[NAME_MAX] = { 0 };printf("请输入要删除人的名字:>");scanf("%s", name);//name为数组名//查找int pos= FindContactByName(pc, name);//删除if (pos == -1){printf("指定的联系人不存在");}else{int j = 0;for (j = pos; j <pc->sz-1 ; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("删除成功\n");}
}void SearchContact(const struct Contact*pc)
{char name[NAME_MAX] = { 0 };printf("输入要查找人的名字:>");scanf("%s", name);int pos = FindContactByName(pc, name);if (-1 == pos){printf("查无此人\n");}else{printf("%15s\t%5s\t%8s\t%15s\t%30s\n", "name", "age", "sex", "tele", "addr");printf("%15s\t%5d\t%8s\t%15s\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(struct Contact* pc)
{char name[NAME_MAX] = { 0 };printf("输入要修改人的名字:>");scanf("%s", name);int pos = FindContactByName(pc, name);if (-1 == pos){printf("要修改的人不存在\n");}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);}}
到这里,我们的简易通讯录已经完成,如果细心的同学会发现我们这个6.sort并没有进行实现,这个我们放到下次再来分析,非常感谢大家的阅读,如果有任何问题,希望大家指正,祝大家offer多多。