课后实践作业
实现简单的菜单设计,提供个人通讯录的管理,例如:
1添加联系人
2显示联系人
3按姓名查询
4按电话查询
5按姓名排序
6删除联系人
0退出
由于刚刚入门,好多想法实现不了,只能换其他简单、
笨的办法,中间好多不会的也是上网搜的ai、csdn....
总之,最后也是写出来了!!
以下是代码,大家有什么改进意见可以畅所欲言,欢迎斧正!!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct contact
{
char name[11];//姓名最多十个字母
char gender;//性别,m(man)表示男,w(woman)表示女
int id;//序号
long long tele;//电话
long long qq;
int class;//班级
struct contact *next;
} CON;
CON *head=NULL;//初始化全局变量head
void menu()//主菜单
{
printf("选择你要进行的操作\n");
printf("1.添加联系人\n2.显示联系人\n3.按姓名查询\n4.按电话查询\n5.按姓名排序\n6.删除联系人\n0.退出\n");
}
void add()//添加联系人并存入文件
{
char name[11],gender;
int id,class,n;
long long tele,qq;
FILE *fp;
if((fp=fopen("contacts.txt","a"))==NULL)//注意这里采用的时追加信息,即在原联系人后继续添加
{
printf("open file error!\n");
exit(1);
}
printf("请输入要添加的联系人个数:\n");
scanf("%d",&n);
printf("请输入要添加的联系人信息:\n");//每人各占一行,每个信息用空格隔开
for(int i=0; i<n; i++)
{
scanf("%s %d %c %lld %lld %d",name,&id,&gender,&tele,&qq,&class);
fprintf(fp,"%s %d %c %lld %lld %d\n",name,id,gender,tele,qq,class);
}
fclose(fp);
}
void save()//将更改后的信息链表存入文件
{
CON *s;
s=head->next;
FILE *fp;
if((fp=fopen("contacts.txt","w"))==NULL)
{
printf("open file error!\n");
exit(1);
}
while(s!=NULL)//遍历整个链表,依次存入文件
{
fprintf(fp,"%s %d %c %lld %lld %d\n",s->name,s->id,s->gender,s->tele,s->qq,s->class);
s=s->next;
}
fclose(fp);
}
void view()//显示联系人信息
{
char name[11],gender;
int id,class;
long long tele,qq;
FILE *fp;
if((fp=fopen("contacts.txt","r"))==NULL)
{
printf("open file error!\n");
exit(1);
}
printf("---------------------------------通讯录---------------------------------\n");
printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
while((fscanf(fp,"%s %d %c %lld %lld %d\n",&name,&id,&gender,&tele,&qq,&class))!=EOF)//判断文件中信息是否存在,存在则打印
printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",name,id,gender,tele,qq,class);
printf("------------------------------------------------------------------------\n");
fclose(fp);
}
CON *chain()//将文件中的联系人信息存在新链表中
{
CON *h,*p,*q;
char name[11],gender;
int id,class;
long long tele,qq;
FILE *fp;
h=(CON*)malloc(sizeof(CON));//表头
p=h;
if((fp=fopen("contacts.txt","r"))==NULL)
{
printf("open file error!\n");
exit(1);
}
while((fscanf(fp,"%s %d %c %lld %lld %d\n",&name,&id,&gender,&tele,&qq,&class))!=EOF)//提取文件中的信息
{
q=(CON*)malloc(sizeof(CON));
strcpy(q->name,name);
q->id=id;
q->gender=gender;
q->tele=tele;
q->qq=qq;
q->class=class;
p->next=q;
p=q;
}//构建链表并存入信息
p->next=NULL;
return h;
}
void search_name()//按姓名查找
{
head=chain();
CON *p=head->next;
char name[11];
printf("请输入您要查找的姓名:\n");
scanf("%s",name);
while(p!=NULL)// 遍历整个链表
{
if(strcmp(name,p->name)==0)//找到目标信息
{
printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",p->name,p->id,p->gender,p->tele,p->qq,p->class);
return ;
}
else
p=p->next;
}
printf("该姓名不存在!\n");
}
void search_tele()//按电话号码查询
{
head=chain();
CON *p;
long long tele;
printf("请输入您要查找的电话:\n");
scanf("%lld",&tele);
p=head->next;
while(p!=NULL)// 遍历整个链表
{
if(p->tele==tele)//找到目标信息
{
printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",p->name,p->id,p->gender,p->tele,p->qq,p->class);
return ;
}
else
p=p->next;
}
printf("该电话不存在!\n");
}
void sort_contact()//按姓名排序信息
{
int swapped;//用于判断是否发生交换
CON* current;//用于遍历链表
CON* last = NULL;//记录最后一个已排序的节点
if (head == NULL)
return;
do
{
swapped = 0;
current = head;
while (current->next != last)//遍历所有已排序之外的节点
{
if (strcmp(current->name, current->next->name) > 0)//发生交换的条件
{
// 交换节点
char name[11],gender;
int id,class;
long long tele,qq;
strcpy(name,current->name);
gender = current->gender;
id=current->id;
tele=current->tele;
qq=current->qq;
class=current->class;
strcpy(current->name, current->next->name);
current->gender = current->next->gender;
current->id = current->next->id;
current->tele = current->next->tele;
current->qq = current->next->qq;
current->class = current->next->class;
strcpy(current->next->name, name);
current->next->gender = gender;
current->next->id = id;
current->next->tele = tele;
current->next->qq = qq;
current->next->class = class;
swapped = 1;
}
current = current->next;
}
last = current;//
}while (swapped); //发生交换继续循环
}
void updateid()//把序号也按姓名顺序排出
{
CON *p;
p=head->next;
int i=1;//i用于更新id的值
while(p!=NULL)
{
p->id=i++;
p=p->next;
}
}
CON delete_contact()//删除联系人信息
{
CON *p1,*p2;
int op;//确定是否删除
head=chain();//提取文件信息创建链表
char name[11];
printf("请输入您要删除的联系人的姓名:\n");
scanf("%s",name);
p1=head->next; //跳过第一个空的结点
if(p1==NULL)
{
printf("List is NULL!\n");
return ;
}
while(strcmp(name,p1->name)!=0&&p1->next!=NULL) //p1指向的不是要找的点,并且后面还有结点
{
p2=p1;
p1=p1->next;//则p1后移一个结点
}
if(strcmp(name,p1->name)==0) //找到要删除的结点
{
printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",p1->name,p1->id,p1->gender,p1->tele,p1->qq,p1->class);
printf("是否要删除该联系人?\n1.是 2.否\n");
scanf("%d",&op);
if(p1==head->next&&op==1)
{
head->next=p1->next; //若p1指向第一个有效结点,则把第2个有效结点地址赋给h->next
printf("删除成功!返回主菜单\n");
}
else if(p1!=head->next&&op==1)
{
p2->next=p1->next;//跳过p1,p2之后直接是p1指向的下一个节点
printf("删除成功!返回主菜单\n");
}
else
{
printf("取消成功!返回主菜单\n");
return;}
free(p1);//释放内存
save();
}
else printf("未找到该联系人!\n"); //找不到指定结点的输出提示
}
int main()
{
int op;
while(1)
{
menu();
scanf("%d",&op);
switch(op)//通过op选择要进行的操作
{
case 1:
add();break;
case 2:
view();break;
case 3:
search_name();break;
case 4:
search_tele();break;
case 5:
{
head=chain();//创建链表存入信息
sort_contact();//按姓名排序节点
updateid();//更新序号
save();//保存
view();//输出链表
}
break;
case 6:
delete_contact();break;
case 0:return 0;
}
}
return 0;
}