PINGDINGSHAN UNIVERSITY 基础编程能力实训报告
题目: 通讯录管理系统
专业年级:计算机科学与技术2013级
姓名: 桂世强
学号: 131210139
2014年06月20日
1 实训题目与要求
1.1 问题描述
通讯录管理系统要求实现通讯录在日常生活中的一些基本操作,建立通讯录文件、删除、排序、查找等操作都要求能成功的在构建的平台上进行准确的处理。
1.2 功能要求
程序输出主菜单(如下),然后提示用户选择操作;
★★★★★★★★★★★★★★★★★★★★★★★★
★欢迎使用通讯录管理系统★
★★★★★★★★★★★★★★★★★★★★★★★★
*************
* 主菜单 *
************************************************
* ㈠:输入; * ㈡:插入;*
************************************************
* ㈢:修改; * ㈣:删除;*
************************************************
* ㈤:查找; * ㈥:排序;*
************************************************
* ㈦:显示; * ㈧:保存;*
************************************************
* ㈨:读取; * ㈩:退出;*
************************************************
在主菜单中选择1,建立文件,输入一定人数的联系人的:姓名、性别、手机号;
在主菜单中选择2,要求用户自己输入要删除的联系人的姓名,然后系统自己找到链表中的联系人并将其删除,要找到联系人并删除会输出“删除成功”,
要是没有找到就会输出“找不到要删除的联系人”;
在主菜单中选择3,要求用户自己输入要查找的联系人的姓名,然后系统自动查找链表中是否有此联系人,有就输出此联系人的姓名、性别、手机号,没有就输出“找不到!”;
在主菜单中选择4,系统会按姓名的字符的大小从大到小输出联系人的姓名、性别、手机号;
在主菜单中选择5,显示通讯录中所有的联系人的信息;
在主菜单中选择6,建立一个number.dat的文件夹,把通讯录里的所有的信息保存在文件夹里,如果出错输出“打不开文件”;
在主菜单中选择7,把number.dat文件夹打开,读出文件夹内的数据,如果出错输出“文件出错”;
在主菜单中选择8,退出系统。
2 系统的设计与功能实现
2.1 总体设计
图1 总体设计
程序通过主模块调用其他函数来实现各种要求实现的功能。
显示主菜单模块通过调用menu函数显示主菜单,提示使用的用户该执行的操作,实现基本的人机对话。
创建链表文件模块通过调用set函数实现新建一个文件存储所要用户信息,
从而实现程序的第一步操作;
插入模块通过调用jia函数实现在已存储的联系人中添加联系人的功能;
修改模块通过调用gai函数实现修改已存储的联系人的信息的功能;
删除模块通过调用del函数实现在数据库中联系人信息的删除功能;
查找模块通过调用find函数实现查找已存储联系人中自己想要的联系人的信息;
排序模块通过调用sort函数实现对已存储的联系人的信息进行排序功能;
显示模块通过调用display函数实现对已存储的联系人的信息的输出的功能;
保存模块通过调用save函数实现对联系人的信息的储存到硬盘上的功能;
读取模块通过调用load函数实现对已存储到硬盘上的联系人的信息的读取的功能;
2.2 数据结构
在程序中为了实现对于通讯录更方便的管理联系人,我们定义了
typedef struct
{
char name[20];
char sex;
char num[12];
}NUMBER;
struct s
{
NUMBER data;
struct s*next;
};
其中https://www.doczj.com/doc/a42124486.html,用来储存联系人的姓名,data.sex用来储存联系人的性别,data.num用来储存联系人的手机号,s是定义链表节点的,data是数据域,naxt是指针域。
2.3 算法设计
图2 主函数的流程图
(1)菜单的设计
①主函数的作用主要是调用menu函数显示主界面,由于菜单比较简单所以采用printf函数将菜单项注意打印在屏幕上,边框则采用printf输出拼接起来实现人机对话的第一步.
②然后通过读取用户的输入,调用switch函数对用户的输入进行进一步的处理,并使用while函数实现用户的选择性的重复操作。
我们为用户提供了一个正常的出口,我们采用人机对话的形式,用户选择某一菜单以后,程序完成对于的功能,用户即可退出也可以继续输入。
(2)设计各模块的算法,这是主板细化的过程。
①为了实现通讯录程序修改模块修改联系人信息的功能,模块调用gai函数以实现这一目的。
函数先定义将要使用变量,然后程序一步步的提示用户进行输入想修改的人的姓名、修改的内容选择、修改等操作。操作完成之后,信息暂时保存在程序开辟的储存空间中,还需调用保存模块将信息保存到硬盘上。
图4 删除函数的流程图
②为了实现用户使用通讯录程序删除的功能,删除模块调用del函数以实现这一功能。
函数先定义将要使用变量,然后程序提示用户进行输入想删除的人的姓名的操作,函数查找文件里是否有该人的信息,如果没有就结束调用,有就删除该联系人。操作完成之后,信息暂时保存在程序开辟的储存空间中,还需调用保存模块将信息保存到硬盘上。
图5 查找函数的流程图
③为了实现用户使用通讯录程序查找的功能,查找模块调用find函数以实现这一功能。
函数先定义将要使用变量,然后程序提示用户进行输入想查找的人的姓名的操作,函数查找文件里是否有该人的信息,如果没有就结束调用,有就输出该联系人的信息。
2.4 程序代码设计
(1)主函数需要读取用户输入的选项,需要成功的调用其他功能的函数,从而实现程序的各个功能。
int j,n; NUM *h;
首先主函数定义变量语句。
while(1)
{
menu();
scanf("%d",&j);
switch(j)
{
case 1: h=set();break;
case 2: h=jia(h);break;
case 3: gai(h);break;
case 4: h=del(h);break;
case 5: find(h);break;
case 6: h=sort(h);break;
case 7: display(h);break;
case 8: save(h);break;
case 9: h=load();break;
case 10: exit(0);
}
}
使用该语句来实现在用户输入选择项后,程序判断后进入对应模块,并相应的调用模块使用的函数进行运算,并使用break在调用完函数后退出switch语句。
通过while语句来确认用户的输入合法性,判断是否继续循环运行程序。
而menu函数简单使用了printf语句来显现将主菜单打印在屏幕上的功能。(2)创建联系人文件的set函数需要5个参数,其中NUM类型的变量p1,h,p2存储临时的姓名、性别、手机号,int i型变量用于记录个数。
int n;
NUM *p1,*h=NULL,*p2;
int i;
int n输入通讯录得人数。根据提示输入联系人的信息。
printf("\n请输入通讯录人数:\n");
scanf("%d",&n);
利用for语句来多次输入联系人的信息,i的自加语句来记录输入记录个数,内嵌的if语句来建立链表。
for(i=1;i<=n;i++)
{
p1=(NUM*)malloc(sizeof(NUM));
printf("\n%d:",i);
scanf("%s %s %s",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
if(i==1)
h=p1;
else p2->next=p1;
p2=p1;
}
(3)通讯录系统的jia函数需要1个变量,NUM类型的变量p1存储临时的姓名、性别、手机号,
NUM *p1;
建立空间,插入联系人的信息,插入到第一个联系人的下面。
p1=(NUM*)malloc(sizeof(NUM));
scanf("%s %s %s",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
p1->next=h->next;
h->next=p1;
(4)通讯录系统的gai函数需要3个变量,其中NUM类型的变量p1,p2存储临
时的姓名、性别、手机号,char类型的变量b[20]记录姓名,int类型的变量j供用户选择修改选项。
int j;
char b[20];
NUM *p1,*p2;
if判断链表是否为空,为空就结束。
if(h==NULL)
return;
输入修改的人的姓名。
printf("\n请输入修改的人的姓名:");
scanf("%s",b);
利用for语句来查找联系人的信息。
for(p1=h;p1;p1=p1->next)
if(strcmp(b,p1->https://www.doczj.com/doc/a42124486.html,)==0)
break;
else
p2=p1;
用if语句来判断是否找到,用switch选择修改。
if(p1)
{
if(strcmp(b,p1->https://www.doczj.com/doc/a42124486.html,) ==0)
{
printf("请输入[1/2/3/](1 修改姓名,2 修改性别,3 修改手机号)\n");
scanf("%d",&j);
switch(j)
{
case 1:printf("请输入要修改的姓名\n");scanf("%s",p1->https://www.doczj.com/doc/a42124486.html,);break;
case 2:printf("请输入要修改的姓别\n");scanf("%s",p1->data.sex);break;
case 3:printf("请输入要修改的手机号\n");scanf("%s",p1->data.num);break;
}
printf("修改成功\n");
}
}
else
printf("找不到要修改的联系人\n");
(5)通讯录系统的del函数需要3个变量,其中NUM类型的变量p1,p2存储临时的姓名、性别、手机号,char类型的变量b[20]记录用户输入的姓名。
char b[20];
NUM *p1,*p2;
printf("\n请输入想删除人的姓名:");
scanf("%s",b);
利用for语句来查找联系人的信息,if进行删除联系人信息。
for(p1=h;p1!=NULL;p1=p1->next)
if(strcmp(b,p1->https://www.doczj.com/doc/a42124486.html,)==0)
break;
else
p2=p1;
if(p1)
{
if(p1==h)
h=p1->next;
else
p2->next=p1->next;
printf("删除成功\n");
free(p1);
}
else
printf("找不到要删除的联系人\n");
(6)通讯录系统的find函数需要2个变量,其中NUM类型的变量p存储临时的姓名、性别、手机号,char类型的变量b[20]记录用户输入的姓名。
char b[20];
NUM *p;
if(h==NULL)
return;
printf("\n请输入想查找人的姓名:");
scanf("%s",b);
利用for语句来查找联系人的信息,if进行判断输出联系人信息。
for(p=h;p;p=p->next)
if(strcmp(b,p->https://www.doczj.com/doc/a42124486.html,)==0)
{
printf("已找到:\n");
printf("姓名\t\t\t性别\t\t\t手机号\n");
printf("%s\t\t\t%s\t\t\t%s\n",p->https://www.doczj.com/doc/a42124486.html,,p->data.sex,p->data.num);
break;
}
if(p==NULL)
printf("找不到联系人!\n");
(7)通讯录系统的sort函数需要3个变量,其中NUM类型的变量p1,p2存储临时的姓名、性别、手机号。NUMBER类型的变量t存储临时的节点。
NUMBER t;
NUM *p1,*p2;
两个for循环采用选择法排序。
for(p1=h;p1->next;p1=p1->next)
for(p2=p1->next;p2;p2=p2->next)
if(strcmp(p1->https://www.doczj.com/doc/a42124486.html,,p2->https://www.doczj.com/doc/a42124486.html,)>0)
{
t=p1->data;
p1->data=p2->data;
p2->data=t;
}
printf("\n输出排序结果:\n");
printf("姓名\t\t\t性别\t\t\t手机号\n");
for(p1=h;p1;p1=p1->next)
printf("%s\t\t\t%s\t\t\t%s\n",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
(8)通讯录系统的display函数需要1个变量,其中NUM类型的变量p存储临时的姓名、性别、手机号。
NUM *p;
利用for语句来输出全部联系人的信息。
printf("姓名\t\t\t性别\t\t\t手机号\n");
for(p=h;p!=NULL;p=p->next)
printf("%s\t\t\t%s\t\t\t%s\n",p->https://www.doczj.com/doc/a42124486.html,,p->data.sex,p->data.num);
(9)通讯录系统的save函数需要2个变量,其中NUM类型的变量p存储临时的姓名、性别、手机号。文件指针fp指向记录文件。
NUM *p;
FILE*fp;
if判断是否建立文件,内嵌的for循环保存联系人信息。fclose(fp)关闭文件。
if((fp=fopen("number.dat","w+"))==0)
{
printf("打不开文件\n");
}
else
{
for(p=h;p;p=p->next)
fprintf(fp,"%s %s %s\n",p->https://www.doczj.com/doc/a42124486.html,,p->data.sex,p->data.num);
}
fclose(fp);
(10)通讯录系统的load函数需要5个变量,其中NUM类型的变量p1,h,p2存储临时的姓名、性别、手机号。文件指针fp指向记录文件。
NUM *p1,*h=NULL,*p2;
int i;
FILE*fp;
if判断是否建立文件,内嵌的for循环读取联系人信息。fclose(fp)关闭文件。
p1=(NUM*)malloc(sizeof(NUM));
printf("姓名\t\t\t性别\t\t\t手机号\n");
if((fp=fopen("number.dat","r+"))==0)
{
printf("文件错误\n");
}
else
for(i=1;!feof(fp);i++)
{
p1=(NUM*)malloc(sizeof(NUM));
fscanf(fp,"%s%s %s\n",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
printf("%s\t\t\t%s\t\t\t%s\n",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
if(i==1)
h=p1;
else p2->next=p1;
p2=p1;
}
p2->next=NULL;
fclose(fp);
2.5 测试与调试
3实训总结
这学期每周我们一节实训上机的时间,虽然上机时间只有短短一节一星期但从中确实学到了不少知识。我觉得我们一定要把基础学扎实,然而实训短短的上机帮我又重新巩固了C语言知识,让我的水平进一步的提高。
实训这是一门纯属于操作的科目,它需用把理论变为上机调试。它对我们来说具有一定的难度。它是编程语言的一门必要学科。我选的实训题目是通讯录管理系统,对这个题目,我觉得很基础。刚开始调试代码的时候有时就是一个很小的错误,导致整个程序不能运行,然而开始的我还没把状态转到学习上,每当程序错误时我都非常焦躁,甚至想到了放弃,但我最终找到了状态,一步一步慢慢来,经过无数次的检查程序错误的原因后慢慢懂得了耐心是一个人成功的必然具备的条件!同时,通过此次课程设计使我了解到,硬件语言必不可缺少,要想成为一个有能力的人,必须懂得硬件基础语言。
在这次课程设计中,虽然不会编写一个十分完美的程序,但是在看程序的过程中,不断的上网查资料以及翻阅相关书籍,通过不断的模索,测试,发现问题,解决问题和在老师的帮助下一步一步慢慢的正确运行程序,终于完成了这次课程设计,虽然这次课程设计结束了但是总觉得自已懂得的知识很是不足,学无止境,以后还会更加的努力深入的学习。
附录
#include
#include
#include
#include
typedef struct
{
char name[20]; //姓名
char sex[3]; /*性别(可以是汉字:男/女)*/
char num[12]; //手机号
}NUMBER;
struct s //定义链表节点{
NUMBER data; //数据域
struct s*next; //指针域
};
typedef struct s NUM; //定义节点类型名为NUM
//输入学生信息并创建链表
NUM* set()
{
int n;
NUM *p1,*h=NULL,*p2;
int i;
system("cls"); //清屏
printf("\n请输入通讯录人数:\n");
scanf("%d",&n);
printf("\n请输入联系人信息:");
printf("姓名、性别、手机号(用空格隔开):\n");
for(i=1;i<=n;i++)
{
p1=(NUM*)malloc(sizeof(NUM));
printf("\n%d:",i);
scanf("%s %s %s",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
if(i==1)
h=p1;
else p2->next=p1;
p2=p1;
}
p2->next=NULL;
printf("按回车键返回:\n");
getch();
return h;
}
//插入函数
NUM* jia(NUM*h)
{
NUM *p1;
system("cls");
printf("\n请输入想添加的联系人信息\n");
printf("姓名、性别、手机号(用空格隔开):\n");
p1=(NUM*)malloc(sizeof(NUM));
scanf("%s %s %s",p1->https://www.doczj.com/doc/a42124486.html,,p1->data.sex,p1->data.num);
p1->next=h->next;
h->next=p1;
printf("按回车键返回:\n");
getch();
return h;
}
//修改函数
NUM* gai(NUM*h)
{
int j;
char b[20];
NUM *p1,*p2;
system("cls");
if(h==NULL)
return;
printf("\n请输入修改的人的姓名:");
scanf("%s",b);
for(p1=h;p1;p1=p1->next)
if(strcmp(b,p1->https://www.doczj.com/doc/a42124486.html,)==0)
break;
else
p2=p1;
if(p1)
{
if(strcmp(b,p1->https://www.doczj.com/doc/a42124486.html,)==0)
{
printf("请输入[1/2/3/](1 修改姓名,2 修改性别,3 修改手机号)\n");
scanf("%d",&j);
switch(j)
{
case 1:printf("请输入要修改的姓名\n");scanf("%s",p1->https://www.doczj.com/doc/a42124486.html,);break;
case 2:printf("请输入要修改的姓别\n");scanf("%s",p1->data.sex);break;
case 3:printf("请输入要修改的手机号\n");scanf("%s",p1->data.num);break;
}
printf("修改成功\n");
}
}
else
printf("找不到要删除的联系人\n");
printf("按回车键返回:\n");
getch();
return h;
}
//删除通讯录信息
NUM* del(NUM *h)
{
char b[20];
NUM *p1,*p2;
system("cls");
printf("\n请输入想删除人的姓名:");
scanf("%s",b);
for(p1=h;p1!=NULL;p1=p1->next)
if(strcmp(b,p1->https://www.doczj.com/doc/a42124486.html,)==0)
break;
else
p2=p1;
if(p1)
{
if(p1==h)
h=p1->next;
else
p2->next=p1->next;
printf("删除成功\n");
free(p1);
}
else
printf("找不到要删除的联系人\n");
printf("按回车键返回:\n");
getch();
return h;
}
//查找联系人
void find(NUM*h)
{
char b[20];
NUM *p;
system("cls");
if(h==NULL) return;
printf("\n请输入想查找人的姓名:");
scanf("%s",b);
for(p=h;p;p=p->next)
if(strcmp(b,p->https://www.doczj.com/doc/a42124486.html,)==0)