设计一个班级同学的通讯录——答案

综合实验1:线性表的应用

一、实验目的

1、利用线性表的基本运算进行线性表的相关操作;

2、掌握文件的应用;

3、加深对链式存储数据结构的理解,逐步培养解决实际问题的编程能力。

二、实验环境

装有Visual C++6.0/CFree的计算机。

本次实验共计4学时。

三、实验内容

(以下内容三选一)

1、通讯录设计

设计一个班级同学的通讯录,要求如下:

  • 通讯录中每个同学的信息包含以下内容:学号(id)、姓名(name)、电话号码(tel)。如果需要更多其他信息,请自行添加。
  • 程序主菜单包含以下几个功能:
  1. 添加记录:通过键盘输入信息,添加一条通讯录记录。
  2. 删除记录:通过键盘输入学号,删除该学号的记录。
  3. 输出记录:输出通讯录全部记录。
  4. 按姓名查找:通过键盘输入姓名,输出该同学的所有信息。
  5. 保存记录:把通讯录中所有的记录保存到文件中。
  6. 清空记录:删除通讯录中的全部记录,并删除文件。
  7. 退出

提示:

  • 程序启动时应判断是否存在记录文件,如果存在,则读取每条记录到链表中。
  • 用户选择并完成主菜单某功能后,除了退出程序,应该返回主菜单。
  • 添加一条记录时,插入到链表的尾部。
  • 查找、删除记录时,如果该记录不存在,则应该输出不存在的提示。
  • 添加记录、删除记录时不需要写文件。
  • 保存记录时,用覆盖写文件的方法。(或者先删除原文件,再保存全部记录信息)
  • 各个功能模块写成函数,由主函数调用。

选做:

  • 主菜单增加一个排序功能选项,可以按照学号从小到大进行排序。排序方法可以用冒泡排序或者插入排序。

下面的代码在Dev-C++ 上获得通过;

英文版本请参照我的另一篇博客:https://blog.csdn.net/CHINA_CNN/article/details/102837088

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h> 
typedef struct Stu
{
long long id;//学生ID 
char name[10];//学生姓名 
long long tel;//学生电话号码 
struct Stu*next;//next链表指针 
}stud;//使用long long长整型是因为int和long的数据类型的长度不足以支持到11位 
FILE *fp; //文件指针,便于接下来对文件进行操作 
void CreLi(stud *&s)//以函数的形式创建链表,方便在主函数中直接调用 
{
s=(stud *)malloc(sizeof(stud));//分配空间 
s->next=NULL;//将头指为空 
}
void Loading(stud * &s,long long ID,char *Name,long long Tel)//将新建的数据以节点形式传入 
{//使用&是为了将载入数据的链表带回主函数 
stud *r,*t=s;//将t指为s,并用while函数指向其末尾; 
while(t->next!=NULL)
{
t=t->next;
}
r=(stud *)malloc(sizeof(stud));//为临时数据的临时节点分配空间 
r->id=ID;
strcpy(r->name,Name);
r->tel=Tel;
//以上三步将传入的值赋给临时节点 
r->next=NULL;//确保末尾指向空 
t->next=(stud*)malloc(sizeof(stud));//为t的下一节点分配空降 
t->next=r;//将临时变量的值赋给t链 
}
bool DeLi(stud * &s,long long ID) //删除记录
{
stud *r=s,*q,*pre=s;
r=r->next;
while(r!=NULL && r->id!=ID)//执行查找 
{
pre=pre->next;
r=r->next;
}
if(r==NULL){//未找到输出提示 
printf("Record does not exist\n");
return false;
}
else//找到则执行删除操作 
{
q=pre->next;//删除值赋给q 
pre->next=q->next;//踢掉待删值 
free(q);//删除完成 
printf("successfully delete\n");
return true;
}
}
void Show(stud *s) //输出联系人 
{
if(s!=NULL)
s=s->next;
if(s!=NULL)
{
while(s!=NULL)//疯狂循环,疯狂输出 
{ 
printf("ID\t\tName\tTel\n");
printf("%lld\t",s->id);
printf("%s\t",s->name);
printf("%lld\n\n",s->tel);
s=s->next;
}
if(s==NULL)
printf("Address book printed!\n");
}
else
{
printf("Address book is empty! Please add contacts first!\n");
}
}
bool NOS(stud *&s,char *Name) //按名字查找
{
stud *p,*pre=s;
p=s->next;
while(p!=NULL&&(strcmp(p->name,Name)))//名字对应查找 
{//strcmp用来判断字符串是否相等,即对链表的遍历 
pre=pre->next;
p=p->next;
}
if(p==NULL)
{
printf("The contact was not found in the address book!\n");
return false;
}
else
{
printf("ID\t\tName\tTel\n");
printf("%lld\t",p->id);
printf("%s\t",p->name);
printf("%lld\n\n",p->tel);
return true;
}
}
void Saving(stud * s) //将内存中的联系人文件存入本地磁盘 
{
fp=fopen("data.txt","w"); //打开文件 
//w是指:打开一个文本文件,清除原内容,写入文件。如果文件不存在,则会创建一个新文件。 
if(s!=NULL)
s=s->next;
while(s!=NULL)
{
fprintf(fp,"%s\t%lld\t%lld\n",s->name,s->id,s->tel);//写入文件,按行写入 
//分别以长整型,字符串,长整型写入txt文件中。 
s=s->next;//每写入一个联系人数据,就将链表指向下一节点。 
}
fclose(fp);//正确的关闭文件,确保真的写入数据 
}
void Empty(stud * &s) //清空记录
{
stud *p=s,*q=s;
p=p->next; 
if(p!=NULL)
q=p->next;//一前一后循环删除 
while(q!=NULL)
{
free(p);//清除临时节点 
p=q;//重给链值 
q=p->next;//指向下一待删节点 
}
free(p);//清除最后一次赋值 
s->next=NULL;//s最终指向空 
printf("Address Book clearance completed\n");
}
void Start(stud *s) // 初始化和载入文件中数据
{
system("color 07"); //屏幕、 字体颜色
char Name[10];
long long ID,Tel;
//a是以追加模式打开文件,不会清除原有数据,若没有,则新建 
fp=fopen("data.txt","a"); //就是为了确保文件没有时可以再建一个 
fclose(fp);
fp=fopen("data.txt","r");//读取原有文件 
while(fscanf(fp,"%s%lld%lld",Name,&ID,&Tel)!=EOF) //从文件中读入数据
Loading(s,ID,Name,Tel);//不停地将文件中的数据写入链表并传出。 
fclose(fp);//确保关闭 
printf("File data read status: read successfully!\n");
}
int main()
{
int n;
long long ID,Tel;
char Name[10];
stud *s;
CreLi(s);
Start(s);
printf("Please select the sequence number you want to operate:\n");
printf("=====  1. Add Records \t2. Delete records   \n");
printf("=====  3. Show record \t4. Search by name   \n");
printf("=====  5. Saving records6. Clear records \n");
printf("=====  7. Sign out\t\t\t\t \n");
while(~scanf("%d",&n))
{
if(n>=1&&n<=6){
switch(n)
{
case 1:
{
printf("Enter student id:\n");
scanf("%lld",&ID);
printf("Enter the name:\n");
scanf("%s",&Name);
printf("Enter phone number:\n");
scanf("%lld",&Tel); 
Loading(s,ID,Name,Tel);break;}
case 2:
{printf("Enter student id:\n");
scanf("%lld",&ID);
DeLi(s,ID);break;}
case 3:
{Show(s);break;}
case 4:
{printf("Enter the name:\n");
scanf("%s",&Name);
NOS(s,Name);break;}
case 5:
{Saving(s);printf("Data saved successfully\n");break;}
case 6:
{Empty(s);break;}
}
}
if(n==7)
{
printf("It's coming to an end. Just a moment, please.\n");
Sleep(3000); 
break;}
printf("=====  1. Add Records \t2. Delete records   \n");
printf("=====  3. Show record \t4. Search by name   \n");
printf("=====  5. Saving records6. Clear records \n");
printf("=====  7. Sign out\t\t\t\t \n");
}
return 0;
}

 

  • 11
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值