这是本人之前做的一个课设,代码比较繁琐(由于当时不想花太多时间以致没有进行压缩)一些但思路比较清晰
注:给出的代码可能由于种种问题复制代码出问题,在此给出源文件:链接:http://pan.baidu.com/s/1pKInR3X 密码:yv6w
一、 课程设计的目的和要求
目的:在已学C语言的基础上,编写一个具有实际功能的程序,掌握实际应用程序开发的基本流程——构思,设计框架,所用知识,程序编写,编译测试,程序完成。
要求:编写一个通讯录,完成显示、添加、查找和修改等操作
二、设计
本次课程设计的通讯录管理系统,本小组共提供了九种基本的功能:
1. 添加联系人
2. 查询联系人
3. 删除联系人
4. 修改联系人信息
5. 输出联系人列表
6. 排序
7. 写入文件
8. 读取文件
9. 通话记录
现在对每个功能进行分析:
添加联系人:
我们设定的联系人信息是由姓名、手机号、QQ、电子邮箱组成,故对其依次输入,而且对于不同的信息对象,我们做出了不同的限定:姓名我们给足了空间(按个人喜好设定联系人姓名),手机号我们限定为11位数字字符串,QQ号码限定为10位数字字符串,电子邮箱只能有一个@号。另外,对于联系人信息的每一项(这里除了姓名),只要输入不符,则重新输入直到你输入的格式正确为止。以下以其中某一项为例进行分析。
以手机号码为例:其中的cala函数用于计算字符串的长度,这里指手机号的长度。
查询联系人:
首先,我们查询的方式可能不同:有些人想查姓名,而有些人查手机号,有些
人则查QQ号码。对于每一项,我们输入想查的信息项,再通过p=head->next
遍历整个链表,依次进行比对,比对成功便输出此项的相关信息,若失败,则
提示“该联系人不存在”。
删除联系人:
删除联系人也很简单,也就是删除链表中的一项,其思路如以下图示:
修改联系人信息:
和查询一样,首先遍历找到所输入的信息项,再进行修改。
输出联系人列表:
通过head指针直接将链表输出。
排序:
如果想要交换链表中两项的位置,则:
写入文件:
通过fp=fopen(filename,"a+")打开文件,通过fprintf按所输入形式往文件写入信息。
读取文件:
通过fp=fopen(filename,"a+")打开文件,通过fgets获取文件中的信息,并用printf
输出。
通话记录:
这里我们设计了一个模拟通话,用一个随机数来表示,假如随机数的值位于链表中项数之内,则在相应的文件中写入联系人信息,如果位于链表项数之外,则在相应文件中写入未知联系人。
三、编码
提示:由于程序的提示信息比较多,同时,为了使得该程序功能更加全面,添加了许多判断,程序比较繁琐,代码量也比较多。
#include
#include
#include
#include
#include
typedef struct chsystem
{
char name[15];//姓名
char tel[20];//手机
char tecent[15];//qq号码
char email[20];//邮箱
}cs;//通讯录结构体
typedef struct pcs
{
cs chat;
pcs* next;
}*ptcs;//通讯录节点
ptcs head=(ptcs)malloc(sizeof(pcs));
int menu_select()//功能选择框
{
char c;
do
{
system("cls");
printf("\n\t\t**********通讯录管理系统**********\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.添加联系人 │\n");
printf("\t\t│ 2.查询联系人 │\n");
printf("\t\t│ 3.删除联系人 │\n");
printf("\t\t│ 4.修改联系人信息 │\n");
printf("\t\t│ 5.输出联系人列表 │\n");
printf("\t\t│ 6.排序 │\n");
printf("\t\t│ 7.写入文件 │\n");
printf("\t\t│ 8.读取文件 │\n");
printf("\t\t│ 9.通话记录 │\n");
printf("\t\t│ 0.退出 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\t\t请您选择(0-9):");
c=getchar();
}while(c<'0'||c>'9');//检查输入是否符合规范
return(c-'0');
}
int cala(char *p)//计算字符串长度
{
int i,n=0;
for(i=0;p[i]!='\0';i++)n++;
return n;
}
int Addpeo()//添加联系人
{
int t,n,a;
char flag='y';
ptcs p=head,q;
while(p->next)p=p->next;
while(flag!='n'&&flag!='N')
{
q=(ptcs)malloc(sizeof(pcs));
p->next=q;
p=q;
q->next=NULL;
printf("\n\t\t请输入:\n");
printf("\t\t姓名:");//输入姓名
scanf("\t\t%s",q->chat.name);
printf("\t\t手机号码:");//输入手机号
scanf("\t\t%s",q->chat.tel);
do
{
n=0;
if(cala(q->chat.tel)!=11)
{
n=1;
printf("\t\t您输入的手机号码格式不存在,请重新输入:");
scanf("\t\t%s",q->chat.tel);
}
else
{
for(t=0;t<11;t++)
{
if(q->chat.tel[t]<'0'||q->chat.tel[t]>'9')
{
n=1;
printf("\t\t您输入的手机号码格式不合理,请重新输入:");
scanf("\t\t%s",q->chat.tel);
break;
}
}
}
}while(n);
printf("\t\tQQ号:");//输入QQ号
scanf("\t\t%s",q->chat.tecent);
do
{
n=0;
if(cala(q->chat.tecent)>10)
{
n=1;
printf("\t\t您输入的QQ号码格式不存在,请重新输入:");
scanf("\t\t%s",q->chat.tecent);
}
else
{
for(t=0;t<10;t++)
{
if(q->chat.tecent[t]<'0'||q->chat.tecent[t]>'9')
{
n=1;
printf("\t\t您输入的QQ号码格式不合理,请重新输入:");
scanf("\t\t%s",q->chat.tecent);
break;
}
}
}
}while(n);
printf("\t\t电子邮箱:");//输入邮箱
scanf("\t\t%s",q->chat.email);
do
{
a=0;
for(t=0;q->chat.email[t]!='\0';t++)
{
if(q->chat.email[t]=='@')
a++;
}
if(a!=1)
{
printf("\t\t输入的邮箱不合理,请重新输入:");
scanf("\t\t%s",q->chat.email);
}
}while(a!=1);
printf("\n\t\t是否继续添加?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int watch_over()//查询联系人
{
int m,n;
char flag='y';
ptcs p=head->next;
while(flag!='n'&&flag!='N')
{
printf("\n\t\t*************查询方式*************\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.查找姓名 │\n");
printf("\t\t│ 2.查找手机号 │\n");
printf("\t\t│ 3.查找QQ号码 │\n");
printf("\t\t│ 4.返回 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\n\t\t请选择查询方式:");
scanf("\t\t%d",&m);//选择查询方式
do
{
n=0;
if(m!=1&&m!=2&&m!=3&&m!=4)
{
n=1;
printf("\t\t您输入的查询方式不存在,请重新输入:");
scanf("\t\t%d",&m);//选择查询方式
}
}while(n);
if(!p)
{
printf("\t\t该通讯录为空!\n");
return 0;
}
if(1==m)
{
char nm[15];
p=head->next;
printf("\t\t请输入您要查询的联系人:");
scanf("\t\t%s",nm);
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)p=p->next;
if(!p)
{
printf("\t\t您要查询的联系人不存在!\n");
printf("\t\t是否继续查询?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
printf("\t\t手机号码:%s\n",p->chat.tel);
printf("\t\tqq号:%s\n",p->chat.tecent);
printf("\t\t电子邮箱:%s\n",p->chat.email);
}
if(2==m)
{
char te[20];
p=head->next;
printf("\t\t请输入您要查询的手机号码:");
scanf("\t\t%s",te);
while(p!=NULL&&strcmp(p->chat.tel,te)!=0)p=p->next;
if(!p)
{
printf("\t\t您要查询的联系人不存在!\n");
printf("\t\t是否继续查询?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
printf("\t\t姓名:%s\n",p->chat.name);
printf("\t\tqq号:%s\n",p->chat.tecent);
printf("\t\t电子邮箱:%s\n",p->chat.email);
}
if(3==m)
{
char qq[15];
p=head->next;
printf("\t\t请输入您要查询的qq号:");
scanf("\t\t%s",qq);
while(p!=NULL&&strcmp(p->chat.tecent,qq)!=0)p=p->next;
if(!p)
{
printf("\t\t您要查询的联系人不存在!\n");
printf("\t\t是否继续查询?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
printf("\t\t姓名:%s\n",p->chat.name);
printf("\t\t手机号:%s\n",p->chat.tecent);
printf("\t\t电子邮箱:%s\n",p->chat.email);
}
if(4==m)return 0;
printf("\t\t是否继续查询?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int Delete()//删除个人信息
{
char nm[20];
char flag='y';
ptcs p=head->next,bh,pre;
if(!p)
{
printf("\t\t该通讯录为空!\n");
return 0;
}
while(flag!='n'&&flag!='N')
{
p=head->next;
printf("\t\t请输入您要删除的联系人姓名:");
scanf("\t\t%s",nm);
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)
{
pre=p;
p=p->next;
}
if(!p)
{
printf("\t\t该联系人不存在!\n");
printf("\t\t是否继续删除?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
bh=p->next;
if(p==head->next)head->next=bh;
else pre->next=bh;
printf("\t\t该联系人已删除!\n");
printf("\t\t是否继续删除?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int changeall(ptcs p)//修改某一联系人的所有信息
{
int a,n,t;
printf("\t\t姓名:");//输入姓名
scanf("\t\t%s",p->chat.name);
printf("\t\t手机号码:");//输入手机号
scanf("\t\t%s",p->chat.tel);
do
{
n=0;
if(cala(p->chat.tel)!=11)
{
n=1;
printf("\t\t您输入的手机号码格式不存在,请重新输入:");
scanf("\t\t%s",p->chat.tel);
}
else
{
for(t=0;t<11;t++)
{
if(p->chat.tel[t]<'0'||p->chat.tel[t]>'9')
{
n=1;
printf("\t\t您输入的手机号码格式不合理,请重新输入:");
scanf("\t\t%s",p->chat.tel);
break;
}
}
}
}while(n);
printf("\t\tQQ号:");//输入QQ号
scanf("\t\t%s",p->chat.tecent);
do
{
n=0;
if(cala(p->chat.tecent)!=10)
{
n=1;
printf("\t\t您输入的QQ号码格式不存在,请重新输入:");
scanf("\t\t%s",p->chat.tecent);
}
else
{
for(t=0;t<10;t++)
{
if(p->chat.tecent[t]<'0'||p->chat.tecent[t]>'9')
{
n=1;
printf("\t\t您输入的QQ号码格式不合理,请重新输入:");
scanf("\t\t%s",p->chat.tecent);
break;
}
}
}
}while(n);
printf("\t\t电子邮箱:");//输入邮箱
scanf("\t\t%s",p->chat.email);
do
{
a=0;
for(t=0;p->chat.email[t]!='\0';t++)
{
if(p->chat.email[t]=='@')
a++;
}
if(a!=1)
{
printf("\t\t输入的邮箱不合理,请重新输入:");
scanf("\t\t%s",p->chat.email);
}
}while(a!=1);
return 0;
}
int changetel(ptcs p)//修改手机号内容
{
int n,t;
scanf("\t\t%s",p->chat.tel);
do
{
n=0;
if(cala(p->chat.tel)!=11)
{
n=1;
printf("\t\t您输入的手机号码格式不存在,请重新输入:");
scanf("\t\t%s",p->chat.tel);
}
else
{
for(t=0;t<11;t++)
{
if(p->chat.tel[t]<'0'||p->chat.tel[t]>'9')
{
n=1;
printf("\t\t您输入的手机号码格式不合理,请重新输入:");
scanf("\t\t%s",p->chat.tel);
break;
}
}
}
}while(n);
return 0;
}
int changeQQ(ptcs p)//修改QQ号码
{
int n,t;
scanf("%s",p->chat.tecent);
do
{
n=0;
if(cala(p->chat.tecent)!=10)
{
n=1;
printf("\t\t您输入的QQ号码格式不存在,请重新输入:");
scanf("\t\t%s",p->chat.tecent);
}
else
{
for(t=0;t<10;t++)
{
if(p->chat.tecent[t]<'0'||p->chat.tecent[t]>'9')
{
n=1;
printf("\t\t您输入的QQ号码格式不合理,请重新输入:");
scanf("\t\t%s",p->chat.tecent);
break;
}
}
}
}while(n);
return 0;
}
int changeEmail(ptcs p)//修改电子邮箱
{
int t,a;
scanf("\t\t%s",p->chat.email);
do
{
a=0;
for(t=0;p->chat.email[t]!='\0';t++)
{
if(p->chat.email[t]=='@')
a++;
}
if(a!=1)
{
printf("\t\t输入的邮箱不合理,请重新输入:");
scanf("\t\t%s",p->chat.email);
}
}while(a==1);
return 0;
}
int change()//修改联系人信息
{
char nm[20],flag='y';
int m,n;
ptcs p=head->next;
if(!p)
{
printf("\t\t该通讯录为空!\n");
return 0;
}
while(flag!='n'&&flag!='N')
{
p=head->next;
printf("\n\t\t*******请输入您要修改的内容*******\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.联系人 │\n");
printf("\t\t│ 2.手机号码 │\n");
printf("\t\t│ 3.QQ号 │\n");
printf("\t\t│ 4.电子邮箱 │\n");
printf("\t\t│ 5.返回 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\n\t\t请输入您要修改的内容:");
scanf("\t\t%d",&m);
do
{
n=0;
if(m!=1&&m!=2&&m!=3&&m!=4&&m!=5)
{
n=1;
printf("\t\t您输入的修改内容不存在,请重新输入:");
scanf("\t\t%d",&m);//选择修改内容
}
}while(n);
if(5==m)return 0;
printf("\t\t请输入您想修改信息的联系人的姓名:");
scanf("\t\t%s",nm);
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)p=p->next;
if(!p)
{
printf("\t\t该联系人不存在!\n");
return 0;
}
if(1==m)
{
printf("\t\t请输入您的修改:\n");
changeall(p);
}
if(2==m)
{
printf("\t\t请输入%s的手机号码:",p->chat.name);
changetel(p);
}
if(3==m)
{
printf("\t\t请输入%s的QQ号:",p->chat.name);
changeQQ(p);
}
if(4==m)
{
printf("\t\t请输入%s的电子邮箱:",p->chat.name);
changeEmail(p);
}
printf("\t\t是否继续修改?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int display()//输出通讯录列表
{
ptcs p=head->next;
if(!p)
{
printf("\t\t该通讯录为空!\n");
return 0;
}
printf("\n\t\t******************************通讯录列表******************************\n");
printf("\t\t姓名\t\t手机号码\tQQ号码\t\t电子邮箱\n");
printf("\t\t----------------------------------------------------------------------\n");
while(p)
{
printf("\t\t%-16s%-16s%-16s%-20s\n",p->chat.name,p->chat.tel,p->chat.tecent,p->chat.email);
p=p->next;
printf("\t\t----------------------------------------------------------------------\n");
}
return 0;
}
int cacu(ptcs p)//计算链表的长度
{
int n=0;
while(p)
{
p=p->next;
n++;
}
return n;
}
int arrange()//对通讯录进行排序,这里本人用冒泡法排序,稍微有些繁琐
{
int i,n;
ptcs pre=head,p=head->next,k,q;
if(!p)
{
printf("\t\t该通讯录为空!\n");
return 0;
}
n=cacu(p);
for(i=0;inext,pre=head;p->next->next!=NULL;pre=p,p=p->next);
{
k=p->next;
q=k->next;
if(strcmp(p->chat.name,k->chat.name)>0)
{
pre->next=k;
k->next=p;
p->next=q;
p=k;
}
}
}
display();
return 0;
}
int write()//将数据写入文件
{
ptcs p=head->next;
FILE* fp;
char filename[30];
if(!p)
{
printf("\t\t该通讯录为空!");
return 0;
}
printf("\t\t写入到文件!\n");
printf("\t\t请输入所写入的文件名:");
scanf("\t\t%s",filename);
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\t\t无法打开文件!\n");
system("pause");
return 0;
}
fprintf(fp,"******************************通讯录列表******************************\n");
fprintf(fp,"姓名\t\t手机号码\tQQ号码\t\t电子邮箱\n");
fprintf(fp,"----------------------------------------------------------------------\n");
while(p)
{
fprintf(fp,"%-16s%-16s%-16s%-20s\n",p->chat.name,p->chat.tel,p->chat.tecent,p->chat.email);
p=p->next;
fprintf(fp,"----------------------------------------------------------------------\n");
}
fprintf(fp,"\n******************************共%d个联系人******************************\n",cacu(head->next));
fclose(fp); //关闭文件
printf("\t\t写入成功!\n");
return 0;
}
int read()//读取文件
{
char str[100],char filename[30];
FILE* fp;
printf("\t\t读取文件!\n");
printf("\t\t请输入所写入的文件名:");
scanf("\t\t%s",filename);
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\t\t无法打开文件!\n");
system("pause");
return 0;
}
while((fgets(str,100,fp))!=NULL)
{
printf("\t\t%s",str);
}
return 0;
}
int call()//呼叫或被呼叫
{
int n;
ptcs p=head->next;
srand((unsigned) time(NULL)); //用时间做种,每次产生随机数不一样
n=rand()%(cacu(p)+5)+1;
return n;
}
int save(int n,char *filename)//保存通话记
{
FILE* fp;
ptcs p=head->next;
int i=1;
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\t\t通话记录将失去!\n");
system("pause");
return 0;
}
if(n<=cacu(p))
{
while(inext;
i++;
}
fprintf(fp,"%-16s%-16s%-16s%-20s\n",p->chat.name,p->chat.tel,p->chat.tecent,p->chat.email);
fprintf(fp,"----------------------------------------------------------------------\n");
}
else fprintf(fp,"未知号码\n");
fclose(fp); //关闭文件
return 0;
}
int chat_record()//通话记录
{
int m,n,i;
char flag='y';
char cal[30]="call.txt",caled[30]="called.txt";
while(flag!='n'&&flag!='N')
{
printf("\t\t模拟通话开始!\n");
printf("\t\t请选择通话类型(1.呼叫(call) OR 2.被呼叫(called)):");
scanf("\t\t%d",&m);
do
{
i=0;
if(m!=1&&m!=2)
{
i=1;
printf("\t\t您输入序号不在标准中,请重新输入:");
scanf("\t\t%d",&m);//选择修改内容
}
}while(i);
n=call();
if(1==m)
save(n,cal);
else if(2==m)
save(n,caled);
printf("\t\t是否继续模拟?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int main()
{
/*head->next=NULL;
system("cls");
printf("\n\t\t**********通讯录管理系统**********\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.添加联系人 │\n");
printf("\t\t│ 2.查询联系人 │\n");
printf("\t\t│ 3.删除联系人 │\n");
printf("\t\t│ 4.修改联系人信息 │\n");
printf("\t\t│ 5.输出联系人列表 │\n");
printf("\t\t│ 6.排序 │\n");
printf("\t\t│ 7.写入文件 │\n");
printf("\t\t│ 8.读取文件 │\n");
printf("\t\t│ 9.通话记录 │\n");
printf("\t\t│ 0.退出 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\t\t请您选择(0-9):");
printf("\n\t\t******************************通讯录列表******************************\n");
printf("\t\t姓名\t\t手机号码\tQQ号码\t\t电子邮箱\n");*/
head->next=NULL;
for(;;)
{
switch(menu_select())
{
case 1:
printf("\n\t\t添加记录到通讯录\n"); //添加记 录
Addpeo();
system("pause");
break;
case 2:
printf("\n\t\t在通讯录中查找联系人\n");
watch_over();
system("pause");
break;
case 3:
printf("\n\t\t从通讯录中删除联系人\n");
Delete();
system("pause");
break;
case 4:
printf("\n\t\t修改通讯录中的信息\n");
change();
system("pause");
break;
case 5:
printf("\n\t\t输出通讯录列表\n");
display();
system("pause");
break;
case 6:
printf("\n\t\t排序\n");
arrange();
system("pause");
break;
case 7:
printf("\n\t\t写入文件\n");
write();
system("pause");
break;
case 8:
printf("\n\t\t读取文件\n");
read();
system("pause");
break;
case 9:
printf("\n\t\t模拟通话\n");
chat_record();
system("pause");
break;
case 0:
printf("\n\t\t谢谢使用,再见!\n"); //结束程序
printf("\n\t\t");
system("pause");
exit(0);
}
}
return 0;
}
四、调试和运行
本次课设调试基本上没有出现什么大问题,都是一些比较细微的问题,其中某个问题是值得注意的,描述如下:
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)p=p->next;//这是正确的形式
而之前,我是这样写的 while(strcmp(p->chat.name,nm)!=0&&p!=NULL)p=p->next;
这就有个问题,当我们的链表到达链尾时,由于其为空,故当我们先判断strcmp(p->chat.name,nm)!=0时会出现错误,因为此时的p不指向任何一个地址。
五、总结(心得体会)
此次的通讯录管理系统总体的难度并不是很难,难的是不断地填充必要或是人性化的功能,以及各个部分分工合理不发生冲突。当然,最重要的还是整个过程沉得下心的心性。
另外,当我们真正的进入社会工作时,绝没有像我们这次课设一样简单,我们如今的工作量或许只是将来我们某个项目中毫不起眼的一项,或许根本就不及,所以,社会工作经验是很重要的。