通讯录目录
用C语言模拟出来一个通讯录,首先要分头文件和源文件的,我这里分了一个头文件和两个源文件: test.c这里用于存放主函数和调用其他函数,contacts.c用于存放通讯录的各种功能函数,contacts.h用于存放引用头文件的代码和自定义函数的声明和预处理指令。 首先,我们写的通讯录鸭油7个功能: 添加联系人,删除联系人,修改联系人的信息,查找联系人,展示通讯录联系人,排序通讯录中的联系人,退出通讯录。 test.c
#include "contacts.h"
enum list
{
exit,
add,
del,
modify,
find,
show,
sort
};
void catalogue()
{
printf("*********************************\n");
printf("*** 1.add 2.del ***\n");
printf("*** 3.modify 4.find ***\n");
printf("*** 5.show 6.sort ***\n");
printf("*** 0.exit ***\n");
printf("*********************************\n");
}
int main()
{
int n = 0;
do
{
catalogue();
printf("请选择>");
scanf("%d", &n);
switch (n)
{
case exit:
printf("退出通讯录");
break;
case add:
break;
case del:
break;
case find:
break;
case modify:
break;
case show:
break;
case sort:
break;
default:
printf("输入错误请重新输入\n");
}
} while (n);
return 0;
}
Contacts.c
#include "contacts.h"
Contacts.h
#include <stdio.h>
运行起来看一下效果:
下面我们就着手安排剩下的功能。
初始化通讯录
首先我们要想一下,通讯录里面的联系人个人信息都有什么,我自己定义的有,名字,年龄,性别,电话,住址。 因为通讯录里面要储存一些联系人,联系人又分这些信息,那么我们用构造体来定义一个联系人再合适不过。 Contacts.h
typedef struct person
{
char name[20];
int age;
char sex[20];
char phone[20];
char location[20];
}person;
这是联系人的类型,那么一个通讯录我们假设能储存一百个人,那么还需要有一个变量来计算一下通讯录当前有多少人才行。 Contacts.h
typedef struct contacts
{
person data[100];
int count;
}contacts;
这里因为data和count是维护整个通讯录的关键变量,count是根据date里面的元素数量变化而变化,放在一个结构体里面更方便用。 然后整个程序就是这样子的: Contacts.h
#include <stdio.h>
#include <string.h>
typedef struct person
{
char name[20];
int age;
char sex[20];
char phone[20];
char location[20];
}person;
typedef struct contacts
{
person data[100];
int count;
}contacts;
void initialize(contacts* pc);
Contacts.c
#include "contacts.h"
void initialize(contacts* pc)
{
pc->count = 0;
memset(pc->data, 0, sizeof(pc->data));
}
test.c
#include "contacts.h"
enum list
{
exit,
add,
del,
modify,
find,
show,
sort
};
void catalogue()
{
printf("*********************************\n");
printf("*** 1.add 2.del ***\n");
printf("*** 3.modify 4.find ***\n");
printf("*** 5.show 6.sort ***\n");
printf("*** 0.exit ***\n");
printf("*********************************\n");
}
int main()
{
int n = 0;
contacts con;
initialize(&con);
do
{
catalogue();
printf("请选择>");
scanf("%d", &n);
switch (n)
{
case exit:
printf("退出通讯录");
break;
case add:
break;
case del:
break;
case find:
break;
case modify:
break;
case show:
break;
case sort:
break;
default:
printf("输入错误请重新输入\n");
}
} while (n);
return 0;
}
这里我们初始化完成了。 这里要说一下,我们传结构体就要传结构体的地址,因为能节省内存。 (这里忘记添加assert函数来断言了,下面补上了)。
添加联系人和展示通讯录的联系人
添加联系人首先要先判断通讯录是不是人数已经满了,然后在contacts结构体中的person data[100]存放联系人的信息,从data[0]开始,那么count就是计算有多少个联系人,一开始也是0,多一个就++,那么count也对应了data数组的下标存放位置。 存放进去之后我们顺便也写一下打印函数,打印就很简单了,定义一个变量来当数组下标,小于count就可以了。 contacts.h
void initialize(contacts* pc);
void addcontact(contacts* pc);
void showcontact(const contacts* pc);
contacts.c
void addcontact(contacts* pc)
{
assert(pc != NULL);
if (pc->count == MAX)
{
printf("通讯录已满\n");
return 0;
}
printf("姓名:");
scanf("%s", pc->data[pc->count].name);
printf("年龄:");
scanf("%d", &(pc->data[pc->count].age));
printf("性别:");
scanf("%s", pc->data[pc->count].sex);
printf("电话号:");
scanf("%s", pc->data[pc->count].phone);
printf("家庭住址:");
scanf("%s", pc->data[pc->count].location);
pc->count++;
printf("增加成功\n");
}
void showcontact(const contacts* pc)
{
assert(pc != NULL);
int i = 0;
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄","性别","电话号","家庭住址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].phone,
pc->data[i].location);
}
}
test.c
int main()
{
int n = 0;
contacts con;
initialize(&con);
do
{
catalogue();
printf("请选择>");
scanf("%d", &n);
switch (n)
{
case exit:
printf("退出通讯录");
break;
case add:
addcontact(&con);
break;
case del:
break;
case find:
break;
case modify:
break;
case show:
showcontact(&con);
break;
case sort:
break;
default:
printf("输入错误请重新输入\n");
}
} while (n);
return 0;
}
来看一下效果:
删除联系人,修改联系人,查找联系人
这三个放在一起写比较方便,因为修改和删除需要先查找有没有这个联系人才可以操作,查找功能更不用说。 首先要写一个查找联系人的函数,用strcmp函数来查找你输入的名字在通讯录里有无。 删除联系人的函数: contacts.c
int find_out(char* p1 , contacts* p2)
{
assert(p1 != NULL);
assert(p2 != NULL);
int i = 0;
for (i = 0; i < p2->count; i++)
{
if (!strcmp(p1, p2->data[i].name))
return i;
}
return -1;
}
int delcontact(contacts* pc)
{
assert(pc != NULL);
char name[20] = { 0 };
printf("输入此人姓名\n");
scanf("%s", name);
int i = find_out(name, pc);
if (i == -1)
{
printf("无此人信息\n");
return 1;
}
pc->count = pc->count - 1;
while (i < pc->count)
{
pc->data[i] = pc->data[i + 1];
i++;
}
printf("删除成功");
}
其实删除人的过程很简单,你选定的元素是data[i],然后被data[i+1]覆盖,data[i+1]被data[i+2]覆盖以此循环。 因为通过一个查找的逻辑找到了此人,所以通讯录的人就会少一人,那么count就会减一,这样让i<count就不会有问题了,如果count不减少,i=99,count=100,就会造成数组的越界访问,这样不好处理,所以我们直接让count- -,这样i最多也就是98,i+1=99;至于data[99]这个位置的元素怎么办,不用理会,上面的添加联系人和展示通讯录都是count进行很重要的操作,新添加的联系人会覆盖掉原来末尾中没有被位移的联系人信息;如果没有添加展示联系人的话根本不会打印出来末尾的那个联系人。 修改联系人就更容易了,直接将原来联系人的信息覆盖掉就可以了,等于无循环版本添加联系人函数。 修改联系人的函数: contacts.c
int find_out(char* p1 , contacts* p2)
{
assert(p1 != NULL);
assert(p2 != NULL);
int i = 0;
for (i = 0; i < p2->count; i++)
{
if (!strcmp(p1, p2->data[i].name))
return i;
}
return -1;
}
int modifycontact(contacts* pc)
{
assert(pc != NULL);
printf("输入此人姓名\n");
char name[20] = { 0 };
scanf("%s", name);
int i = find_out(name, pc);
if (i == -1)
{
printf("无此人信息\n");
return 1;
}
printf("请输入要修改的信息\n");
printf("姓名:");
scanf("%s", pc->data[i].name);
printf("年龄:");
scanf("%d", &(pc->data[i].age));
printf("性别:");
scanf("%s", pc->data[i].sex);
printf("电话号:");
scanf("%s", pc->data[i].phone);
printf("家庭住址:");
scanf("%s", pc->data[i].location);
printf("修改成功\n");
}
查找联系人的函数就是展示通讯录函数的无循环版本。 这是查找联系人的函数: contacts.c
int find_out(char* p1 , contacts* p2)
{
assert(p1 != NULL);
assert(p2 != NULL);
int i = 0;
for (i = 0; i < p2->count; i++)
{
if (!strcmp(p1, p2->data[i].name))
return i;
}
return -1;
}
int findcontact(contacts* pc)
{
assert(pc != NULL);
printf("输入此人姓名\n");
char name[20] = { 0 };
scanf("%s", name);
int i = find_out(name, pc);
if (i == -1)
{
printf("无此人信息\n");
return 1;
}
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址");
printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].phone,
pc->data[i].location);
}
这是代码运行的效果(写一点调试一点,这样就会让代码的bug容易修复):
排序通讯录
排序我也按照通讯录中联系人的名字来排序,这就用到了之前的函数,qsort。 contacts.c
int estimate(const void* p1, const void* p2)
{
return strcmp(((person*)p1)->name, ((person*)p2)->name);
}
void sortcontact(contacts* pc)
{
assert(pc != NULL);
qsort(pc->data, pc->count, sizeof(person), estimate);
printf("排序成功\n");
}
看看是否有问题: 没问题。
完整的代码
contacts.h
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define MAX 100
typedef struct person
{
char name[20];
int age;
char sex[20];
char phone[20];
char location[20];
}person;
typedef struct contacts
{
person data[100];
int count;
}contacts;
void initialize(contacts* pc);
void addcontact(contacts* pc);
void showcontact(const contacts* pc);
int delcontact(contacts* pc);
int modifycontact(contacts* pc);
int findcontact(contacts* pc);
void sortcontact(contacts* pc);
contacts.c
#include "contacts.h"
int find_out(char* p1, contacts* p2)
{
assert(p1 != NULL);
assert(p2 != NULL);
int i = 0;
for (i = 0; i < p2->count; i++)
{
if (!strcmp(p1, p2->data[i].name))
return i;
}
return -1;
}
void initialize(contacts* pc)
{
assert(pc != NULL);
pc->count = 0;
memset(pc->data, 0, sizeof(pc->data));
}
void addcontact(contacts* pc)
{
assert(pc != NULL);
if (pc->count == MAX)
{
printf("通讯录已满\n");
return 0;
}
printf("姓名:");
scanf("%s", pc->data[pc->count].name);
printf("年龄:");
scanf("%d", &(pc->data[pc->count].age));
printf("性别:");
scanf("%s", pc->data[pc->count].sex);
printf("电话号:");
scanf("%s", pc->data[pc->count].phone);
printf("家庭住址:");
scanf("%s", pc->data[pc->count].location);
pc->count++;
printf("增加成功\n");
}
void showcontact(const contacts* pc)
{
assert(pc != NULL);
int i = 0;
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].phone,
pc->data[i].location);
}
}
int delcontact(contacts* pc)
{
assert(pc != NULL);
char name[20] = { 0 };
printf("输入此人姓名\n");
scanf("%s", name);
int i = find_out(name, pc);
if (i == -1)
{
printf("无此人信息\n");
return 1;
}
pc->count = pc->count - 1;
while (i < pc->count)
{
pc->data[i] = pc->data[i + 1];
i++;
}
printf("删除成功\n");
}
int modifycontact(contacts* pc)
{
assert(pc != NULL);
printf("输入此人姓名\n");
char name[20] = { 0 };
scanf("%s", name);
int i = find_out(name, pc);
if (i == -1)
{
printf("无此人信息\n");
return 1;
}
printf("请输入要修改的信息\n");
printf("姓名:");
scanf("%s", pc->data[i].name);
printf("年龄:");
scanf("%d", &(pc->data[i].age));
printf("性别:");
scanf("%s", pc->data[i].sex);
printf("电话号:");
scanf("%s", pc->data[i].phone);
printf("家庭住址:");
scanf("%s", pc->data[i].location);
printf("修改成功\n");
}
int findcontact(contacts* pc)
{
assert(pc != NULL);
printf("输入此人姓名\n");
char name[20] = { 0 };
scanf("%s", name);
int i = find_out(name, pc);
if (i == -1)
{
printf("无此人信息\n");
return 1;
}
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址");
printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].phone,
pc->data[i].location);
}
int estimate(const void* p1, const void* p2)
{
return strcmp(((person*)p1)->name, ((person*)p2)->name);
}
void sortcontact(contacts* pc)
{
assert(pc != NULL);
qsort(pc->data, pc->count, sizeof(person), estimate);
printf("排序成功\n");
}
test.c
#include "contacts.h"
enum list
{
EXIT,
ADD,
DEL,
MODIFY,
FIND,
SHOW,
SORT
};
void catalogue()
{
printf("*********************************\n");
printf("*** 1.add 2.del ***\n");
printf("*** 3.modify 4.find ***\n");
printf("*** 5.show 6.sort ***\n");
printf("*** 0.exit ***\n");
printf("*********************************\n");
}
int main()
{
int n = 0;
contacts con;
initialize(&con);
do
{
catalogue();
printf("请选择>");
scanf("%d", &n);
switch (n)
{
case EXIT:
printf("退出通讯录\n");
break;
case ADD:
addcontact(&con);
break;
case DEL:
delcontact(&con);
break;
case FIND:
findcontact(&con);
break;
case MODIFY:
modifycontact(&con);
break;
case SHOW:
showcontact(&con);
break;
case SORT:
sortcontact(&con);
break;
default:
printf("输入错误请重新输入\n");
}
} while (n);
return 0;
}
|