要求
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
程序代码
根据所提出的要求可先创建一个结构体来存放联系人的具体信息,为了构成一个通讯录,在每个结构体的后面都跟上下一个结构体的地址,这样通过上一个结构体就可以找到下一个结构体,使整个通讯录都连在一起
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <string.h>
struct Person//定义结构体,存储联系人的信息
{
char *name;//姓名
char gender[5];//性别
int age;//年龄
char phone[12];//电话号码
char *address;//地址
struct Person *next;//下一个联系人的首地址
};//让每个结构体都存上下一个结构体的地址,构成链表,动态存储联系人
int content()//在修改联系人的参数中需选择的
{
printf("---- 1.姓名 ----\n");
printf("---- 2.性别 ----\n");
printf("---- 3.年龄 ----\n");
printf("---- 4.电话号码 ----\n");
printf("---- 5.地址 ----\n");
printf("---- 0.取消 ----\n");
int input = 0;
printf("选择要修改的内容");
scanf("%d", &input);
return input;
}
int menu()//菜单,把选择的数字返回
{
printf("****************************\n");
printf("**** 通讯录 ****\n");
printf("**** 1.添加 2.删除 ****\n");
printf("**** 3.查找 4.修改 ****\n");
printf("**** 5.显示 6.清空 ****\n");
printf("**** 7.排序 0.退出 ****\n");
printf("****************************\n");
int input = 0;
printf("请选择:");
scanf("%d", &input);
return input;
}
void add(struct Person **start)//添加联系人
{
struct Person *p = malloc(sizeof(struct Person));//在堆上动态开辟内存来存放结构体
char buf1[50] = { 0 };//在栈上创建一个字符数组,临时存放联系人的姓名
printf("姓名:");
scanf("%s", buf1);
char *temp1 = malloc(strlen(buf1) + 1);//在堆上开辟一个大小与这个姓名所占相同大小的内存
strcpy(temp1, buf1);//把栈上数组的内容拷贝到堆上
p->name = temp1;//让表示姓名的指针指向这块空间
printf("性别:");
scanf("%s", p->gender);
printf("年龄:");
scanf("%d", &(p->age));
printf("电话号码:");
scanf("%s", p->phone);
char buf2[200] = { 0 };
printf("地址:");
scanf("%s", buf2);
char *temp2 = malloc(strlen(buf2) + 1);
strcpy(temp2, buf2);
p->address = temp2;
p->next = NULL;
if (*start == NULL)
{
*start = p;
}
else
{
struct Person *s = *start;
while (s->next != NULL)
{
s = s->next;
}
s->next = p;
}
}
void del(struct Person **start)//删除联系人
{
char name[20] = { 0 };
printf("请输入要删除的联系人:");
scanf("%s", name);
struct Person *sta = NULL;
struct Person *end = *start;
while (end)
{
if (strcmp(end->name, name) == 0)
{
break;
}
else
{
sta = end;
end = end->next;
}
}
if (sta == NULL)//当sta为NULL时,说明第一个就是要删除的联系人
{
*start = end->next;//把第一个结构体所指的位置移动到第二个联系人
free(end);//销毁第一个联系人
end = NULL;
printf("已删除\n");
}
else
{
if (end != NULL)//当end不为空时说明找到了这个联系人
{
sta->next = end->next;//让sta从之前指向的位置跳到所要删除的联系人之后
free(end);//销毁要删除的联系人
end = NULL;
printf("已删除\n");
}
}
}
void find(struct Person *start)//查找联系人
{
char name[20] = {0};
printf("请输入要查找的联系人:");
scanf("%s", name);
struct Person *people = start;
while (people)
{
if (strcmp(people->name, name) == 0)
{
printf("姓名:%s\n", people->name);
printf("性别:%s\n", people->gender);
printf("年龄:%d\n", people->age);
printf("电话:%s\n", people->phone);
printf("住址:%s\n", people->address);
printf("\n");
break;
}
else
{
people = people->next;
}
}
if (people == NULL)
{
printf("通讯录中没有此人!\n");
}
}
void revise(struct Person *start)//修改联系人
{
int input;
struct Person *people = start;
char name[20] = { 0 };
printf("请输入要修改的联系人:");
scanf("%s", name);
enum Choose//定义枚举类型,使条件语句中的case语句更易懂
{
EXIT,
NAME,
GENDER,
AGE,
PHONE,
ADDRESS
};
while (people)
{
if (strcmp(people->name, name) == 0)
{
do
{
input = content();
switch (input)
{
case NAME:
{
char buf1[50] = { 0 };
printf("姓名:");
scanf("%s", buf1);
char *temp1 = malloc(strlen(buf1) + 1);
strcpy(temp1, buf1);
people->name = temp1;
}
break;
case GENDER:
{
printf("性别:");
scanf("%s", people->gender);
}
break;
case AGE:
{
printf("年龄:");
scanf("%d", &(people->age));
}
break;
case PHONE:
{
printf("电话号码:");
scanf("%s", people->phone);
}
break;
case ADDRESS:
{
char buf2[200] = { 0 };
printf("地址:");
scanf("%s", buf2);
char *temp2 = malloc(strlen(buf2) + 1);
strcpy(temp2, buf2);
people->address = temp2;
}
break;
case EXIT:
printf("退出修改!\n");
break;
default:
printf("选择错误,请重新选择:\n");
break;
}
} while (input);
break;
}
else
{
people = people->next;
}
}
}
void show(struct Person *start)//展示通讯录
{
while(start)
{
printf("姓名:%s\n", start->name);
printf("性别:%s\n", start->gender);
printf("年龄:%d\n", start->age);
printf("电话:%s\n", start->phone);
printf("住址:%s\n", start->address);
printf("\n");
start = start->next;
}
}
void empty(struct Person **start)//清空通讯录
{
struct Person *temp = *start;
while (*start)//让start循环指向下一个结构体,一个个销毁
{
*start = (*start)->next;
free(temp);
temp = NULL;
if (*start != NULL)
{
struct Person *temp = *start;
}
}
}
void sort(struct Person **start)//按名字排序
{
struct Person *left = *start;
struct Person *right = left->next;
struct Person *flag = left;
char temp1[100] = { 0 };
int temp2 = 0;
while (right)
{
if (strcmp(left->name, right->name) > 0)
{
strcpy(temp1, left->name);
strcpy(left->name, right->name);
strcpy(right->name, temp1);
strcpy(temp1, left->gender);
strcpy(left->gender, right->gender);
strcpy(right->gender, temp1);
temp2 = left->age;
left->age = right->age;
right->age = temp2;
strcpy(temp1, left->phone);
strcpy(left->phone, right->phone);
strcpy(right->phone, temp1);
strcpy(temp1, left->address);
strcpy(left->address, right->address);
strcpy(right->address, temp1);
}
if (right->next == NULL)
{
left = flag->next;
right = left->next;
flag = left;
}
else
{
left = right;
right = right->next;
}
}
}
void address_list()
{
int input;
struct Person *start = NULL;
enum Choose//定义一个枚举函数,默认从0开始
{
EXIT,
ADD,
DEL,
FIND,
REVISE,
SHOW,
EMPTY,
SORT
};
do
{
input = menu();
switch(input)
{
case ADD:
add(&start);
break;
case DEL:
del(&start);
break;
case FIND:
find(start);
break;
case REVISE:
revise(start);
break;
case SHOW:
show(start);
break;
case EMPTY:
empty(&start);
break;
case SORT:
sort(&start);
break;
case EXIT:
printf("退出通讯录!\n");
break;
default:
printf("选择错误,请重新选择:\n");
break;
}
} while (input);
}
int main()
{
address_list();
system("pause");
return 0;
}