通讯录(通过链表实现)
设计并实现一个简易的通讯录软件,管理个人通讯记录。一条通讯记录可包括:
姓名、工作单位、手机、住宅电话、E-Mail、家庭住址等(可自行增删,但不可过少)。
该系统应实现以下基本功能:
(1)增加新的通讯记录。
(2)删除已有的通讯记录。
(3)修改已有的通讯记录。
(4)浏览全部或指定(如指定姓名、工作单位等)的通讯记录。
(5)合理组织排列各项功能,界面可使用键盘操作。
(6)以文件的形式存储数据。
样例1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char filename[10] = {"txl"};
FILE *fp;
struct ListNode {
char name[30];
char work[30];
char tel[30];
char addr[50];
struct ListNode *next;
};
struct ListNode *createlist() //通讯录的建立
{
struct ListNode *head=NULL,*p,*last;
int flag = 1; //用于判断是否结束联系人的输入
last=head;
while(flag){
p=(struct ListNode*)malloc(sizeof(struct ListNode)); //申请新结点
printf("名字\t工作单位\t电话\t地址\n");
scanf("%s%s%s%s", p->name, p->work, p->tel, p->addr);
p->next = NULL; //新结点为空,
if(head == NULL)//若为头结点,则让head指向p
head = p;
else //非头结点,则连接在上一个结点
last->next = p;
last = p; //让last指向p,移动标志位到新结点
printf("\n输入1继续输入新的联系人,输入0退出输入\n");
scanf("%d", &flag);
}
return head;
}
void insertNode(ListNode *head,ListNode *p) //插入联系人
{
ListNode *p1, *p2;
p1 = head;
p2 = p1->next;
while(p2 != NULL){
p1 = p2; //p1指向刚访问过的结点
p2 = p2->next; //p2指向表的下一个结点
}
p1->next = p; //插入p所指向的结点
p->next = p2; //连接表中剩余部分
}
ListNode *listfind(ListNode *head) //查找联系人
{
ListNode *p;
char temp[30]; //先存储要找的人 的名字
printf("请输入名字查找\n");
scanf("%s", temp);
if(strcmp(head->name,temp) == 0)//如果通讯录第一个是要找的人直接返回头结点
return head;
p = head->next; //如果不是第一个则往下找
while(p && strcmp(p->name,temp) != 0){//如果没找完最后一个联系人 或者是 已经找的联系人
p = p->next; //p往下移动
}
return p; //返回联系人的位置
}
void delnode(ListNode *head)//删除联系人
{
ListNode *p, *q;
int flag;
p = listfind(head); //调用查找函数
if(p == NULL){ //如果没有找的则结束删除
printf("没有查到要删除的通讯者!\n");
return;
}
printf("已找到,输入1删除,输入0结束操作\n");
scanf("%d", &flag);
if(flag){
q = head;
if(strcmp(head->name,p->name) == 0){ //如果要删除的联系人是头结点
q = q->next; //先让p变成第二个结点
head = q; //在让头结点后移 完成头结点的删除
}
else{ //如果不是头结点
while(q != NULL && q->next != p)
q = q->next; //找到 要删除的联系人前一个节点
q->next = p->next; //删除结点
printf("通讯者已被删除!\n");
}
}
}
void changenode(ListNode *head)
{
ListNode *p, *q;
int flag;
p = listfind(head); //调用查找函数
if(p == NULL){ //如果没有找的则结束删除
printf("没有查到要删除的通讯者!\n");
return;
}
printf("已找到,输入1修改名字,输入2修改工作单位,输入3修改电话,输入4修改地址\n");
while(1){
scanf("%d", &flag);
if(flag > 0 && flag < 4) break;
printf("输入错误,请重新输入!\n");
}
printf("请输入");
switch(flag){
case 1:printf("新名字\n"); break;
case 2:printf("新工作单位\n"); break;
case 3:printf("新电话\n");break;
case 4:printf("新地址\n");break;
}
char temp[30];
getchar();
gets(temp);
switch(flag){
case 1:strcpy(p->name,temp); break;
case 2:strcpy(p->work,temp); break;
case 3:strcpy(p->tel,temp); break;
case 4:strcpy(p->addr,temp); break;
}
printf("修改成功!\n");
}
void printlist( struct ListNode *L )//输出联系人名单
{
struct ListNode *p = L;
while (p) {
printf("%s\n%s\n%s\n%s\n\n", p->name, p->work, p->tel, p->addr);
p = p->next;
}
}
int menu_select(){ //选择菜单
int A;
printf("\n=============================================\n"
"* 通讯录管理系统 *\n"
"=============================================\n"
" 1.通讯录的建立\n"
" 2.通讯录的插入\n"
" 3.通讯录的查询\n"
" 4.通讯录的删除\n"
" 5.通讯录的输出\n"
" 6.通讯录的修改\n"
" 0.退出管理系统\n"
"=============================================\n\n"
"请选择0-6:\n");
while(1){ //输入的范围在0~5
scanf("%d", &A);
if(A < 0 || A > 6)
printf("\n输入错误,重选0-6:\n");
else
break;
}
return A;
}
void save(ListNode *head)//存储联系人在文件中
{
ListNode *p = head;
if((fp = fopen(filename,"w")) == NULL){
printf("无法打开此文件!\n");
exit(0);
}
while(p){ //将每一个结点依次写入文件
fprintf(fp,"%s\n%s\n%s\n%s\n\n", p->name, p->work, p->tel, p->addr);
p = p->next;
}
fclose(fp);
}
void printtxl() //文件中联系人的输出
{
char ch;
if((fp = fopen(filename,"r")) == NULL){
printf("无法打开此文件!\n");
exit(0);
}
ch = getc(fp); ///逐一输出文件字符直到文件结束EOF
while(ch != EOF){
putchar(ch);
ch = getc(fp);
}
fclose(fp);
}
int main()
{
int t;
ListNode *head, *p;
while(1){
switch(menu_select()){ //选择菜单中的选项之后 指向该选项的操作
case 1:
printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
"* 通讯录链表的建立 *\n"
"+++++++++++++++++++++++++++++++++++++++++++++++\n");
head = createlist();
break;
case 2:
printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
"* 通讯者信息的添加 *\n"
"+++++++++++++++++++++++++++++++++++++++++++++++\n"
"名字 工作单位 电话 地址\n");
p = (ListNode *)malloc(sizeof(ListNode));
scanf("%s%s%s%s", p->name, p->work, p->tel, p->addr);
insertNode(head,p);
break;
case 3:
printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
"* 通讯录信息的查询 *\n"
"+++++++++++++++++++++++++++++++++++++++++++++++\n");
p = listfind(head);
if(p != NULL){
printf("-----------------------------------------------\n"
"名字 工作单位 电话 地址\n"
"-----------------------------------------------\n"
"%s\n%s\n%s\n%s%\n"
"-----------------------------------------------\n", p->name, p->work, p->tel,p->addr);
}
else
printf("没查到要查询的通讯者!\n");
break;
case 4:
printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
"* 通讯录信息的删除 *\n"
"+++++++++++++++++++++++++++++++++++++++++++++++\n");
delnode(head);
break;
case 5:
printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
"* 通讯录的输出 *\n"
"+++++++++++++++++++++++++++++++++++++++++++++++\n");
printlist(head);
break;
case 6:
printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
"* 通讯录的修改 *\n"
"+++++++++++++++++++++++++++++++++++++++++++++++\n");
changenode(head);
break;
case 0:
printf("\n 退出系统!\n");
t = 0;
break;
}
if(t == 0)
break;
}
printf("已经储存在文件中的联系人\n");
save(head);
printtxl();
return 0;
}