C程序设计实习报告
题目:手机通信录管理系统设计
学 院: 机械与电子信息学院 专 业: 机械设计制造及其自动化 姓 名: 班级学号: 072093-15
指导教师: 薛思清
2011 年 7 月 1 日
目录
一 需求分析 ................................................................................. - 3 -
1.1基本要求 ............................................................................... - 3 -
二 概要设计 ................................................................................. - 3 -
三 详细设计 ................................................................................. - 4 -
3.1主函数................................................................................... - 5 -
3.2 各功能模块设计 ................................................................... - 6 -
3.2.1浏览模块........................................................................ - 7 -
3.2.2查看模块........................................................................ - 7 -
3.2.3增加模块........................................................................ - 9 -
3.2.4修改模块...................................................................... - 10 -
3.2.5删除模块...................................................................... - 11 -
3.3公共函数 ..............................................................................- 11 -
3.3.1保存函数...................................................................... - 11 -
3.3.2加载函数...................................................................... - 12 -
四 运行截图 ............................................................................... - 12 -
五 个人心得与总结 ...................................................................... - 16 - 参考文献....................................................................................... - 16 - 附录 .............................................................................................. - 16 - - 2 -
一 需求分析
1.1基本要求
该系统模拟手机通讯录管理系统,实现对手机中的通讯录进行管理 要能提供以下几种功能:
(1)查看功能:选择此功能时,列出下列三类选择:
A:办公类 B:个人类 C:商务类
(2)当选中某类时,显示出此类所有数据中的姓名和电话号码
(3)添加数据功能:能录入新数据,每个结点包括:姓名,电话号码,分类(可能选项有:w为办公类 p为个人类 b为商务类),电子邮件。 例如: 杨春 135xxxxxxxx 商务类 chuny@126.com 。 当录入重复的姓名和电话号码时,则提示数据录入重复并取消录入;当通讯录中超过15条信息时,存储空间已满,不能再录入新数据;录入的新数据能按递增的顺序自动进行条目编号。
(4)修改功能:选中某个人的姓名时,可对此人的相应数据进行修改。
(5)删除功能:选中某个人的姓名时,可对此人的相应数据进行删除,并自动调整后续条目的编号。
二 概要设计
- 3 -
首先,因为每个个体有多种信息,所以要建立结构体来储存和整合各个信息。然后利用模块来分别实现程序的各个功能。各个模块用函数来实现。在通过通过主函数来判断输入字母,从而调动函数,实现所需功能。最后将输入的文件保存在文件里,以便重复使用。根据功能需要建立显示,添加,查看,删除,修改,保存五个模块。在模块中通过调用各个函数来实现功能。系统机构图如下
三 详细设计
根据功能需要建立浏览,查看,添加,删除,
修改五个模块。在模块中通过调用各个函数来实图3-1
现功能。详细设计如下:
- 4 -
3.1主函数
主函数一般设计得比较简洁,只提供输入,处理和输出部分的函数调用。本程序中鉴main()函数体内的界面选择部分语句单独抽取出来作为一独立函数,目的在于系统执行完每部分功能模块后能够方便返回到系统界面,其流程图如图3-1所示.主函数形式如下: void menu() /*主界面*/
{int n,w1,a,i,b;
b=load();
puts("\t\t***************菜单***************\n\n");
puts("\t\t\t\t1.浏览");
puts("\t\t\t\t2.查看");
puts("\t\t\t\t3.增加");
puts("\t\t\t\t4.修改");
puts("\t\t\t\t5.删除");
puts("\t\t\t\t6.退出");
printf("请选择(1-6): ");
scanf("%d",&n);
if(n<1||n>6) /*对选择的数字做判断*/
{
w1=1;getchar();}
else w1=0;
while(w1==1);
switch(n)
{
case 1:scan();break; /*浏览模块*/
case 2:browse();break; /*查看模块*/
case 3:addition();break; /*增加模块*/
case 4:modify();break; /*修改模块*/
- 5 -
case 5: {
puts("\t\t***************删除***************\n\n"); /*删除模块*/
for(i=1;i<b;i++)
printf("%d> %10s%20s%20s%20s\n",i,N);
printf("选择你要删除的信息的编号: ");
scanf("%d",&a);
}
}
/***************主函数***************/
main()
{
menu();
} del(a);} break; case 6:exit(0); /*退出*/
3.2 各功能模块设计
在设计程序之前,先分析数据结构,看各数据信息,名字、分类、邮件地址是字符型,可采用字符型数组;号码为整数,但长整型只能容纳十位数,而号码有十一位数,所以号码不能采用整型,应采用字符型,所以从整体上看,可以用结构体的形式把通信人的名字、号码、分类、邮件地址作为结构体的成员,用结构体数组存放若干个通信人的信息。结构体设计如下:
struct people
{
char name[10];
char num[11];
char kind[20];
char email[20];}
- 6 -
peo[15]; /*数组中每个数组元素对应一个通信人*/
3.2.1浏览模块
该模块的功能是显示所有通信人的信息,其流程图如图3-2,其函数内容如下: /*******************浏览模块*******************/ void scan() {
int i,b;
for(i=1;i<b;i++)
printf("%d> %10s%11s%20s%20s\n\n",i,N); printf("任意输入返回主菜单"); getchar(); getchar(); menu(); }
图3-2 浏览模块流程图
3.2.2查看模块
该模块的功能是按个人类.商务类/办公类三
类查找符合选定类型的所有通信人的信息,并输出所有符合该类型通信人的信息,该模块具体设计如下:
/***************查看模块***************/ void browse() {
int i,a,b; char c;
b=load();
puts("\t\t******************************\n\n");
查
看
图3-3查看览模块流程
- 7 -
puts("\t\t\t\t1.办公类");
puts("\t\t\t\t2.个人类");
puts("\t\t\t\t3.商务类");
printf("请选择需查看的类别(1-3): []\b\b");
scanf("%d",&a);
switch(a)
{ case 1: { printf("办公类有:\n");
printf(" 姓 名 号 码 分 类 邮 件 地 址\n");
for(i=1;i<b;i++)
{
if(strcmp(peo[i].kind,"办公类")==0)
printf("%10s%11s%20s%20s\n",N);
}
}
break;
case 2:{ printf("个人类有:\n");
printf(" 姓 名 号 码
地 址\n");
for(i=1;i<b;i++)
{
if(strcmp(peo[i].kind,"个人类")==0)
printf("%10s%11s%20s%20s\n",N);
}
}break;
case 3: { printf("商务类有:\n");
printf(" 姓 名 号 码
地 址\n");
for(i=1;i<b;i++)
{
if(strcmp(peo[i].kind,"商务类")==0)
printf("%10s%11s%20s%20s\n",N);
}
}break;
}
printf("\n是否继续查看?(y/n)\n");
getchar();
c=getchar();
switch(c)
{
case 'y':browse();break;
default:menu();}
- 8 - 分 类 分 类 邮 件 邮 件
}
3.2.3增加模块
该模块可实现增加功能,使用户能够输入一个通信人的信息后能保存到文件中,并判断输入信息是否与之前的信息重复,如果重复则不保存该信息,信息满十五条后不能再输入,该模块流程图如图3-4,该模块的具体设计如下: /***************增加模块***************/ void addition() {int j,b;
puts("\t\t***************增加***************\n\n");调用 printf("请输入相关信息\n\n"); b=load();
if(b>15) /*判断是否满十五条信息*/ {
printf("信息已满\n");
menu(); }
printf("姓名:"); scanf("%8s",peo[b].name); printf("号码scanf("%11s",peo[b].num); printf("分类
scanf("%20s",peo[b].kind); printf("邮件地址scanf("%20s",peo[b].email);
for(j=1;j<b;j++) {
if((strcmp(peo[b].name,peo[j].name)==0)||strcmp(peo[b].num,peo[j].num)==0)
{ printf("输入重复:"); /*判断是否与之前的信息重复*/ save(b); del(b); } else save(b); }
getchar(); getchar(); menu(); }
- 9 -
3.2.4修改模块
该模块的功能是显示所有通信人的信息,用户输入要修改通信人的序号,并根据提示修改该通信人的哪部分信息,根据用户的选择修改相应的信息,该模块流程图如图3-5.该模块的设计如下:
/***************修改模块***************/
void modify()
{ int i,a,b,d;
char c;
puts("\t\t***************修改***************\n\n");
b=load();
for(i=1;i<b;i++)
printf("%d>%10s%11s%20s%20s\n",i,N);
printf("选择你要修改的信息编号: []\b\b");
scanf("%d",&a);
printf("请选择你要修改的项目\n<1>姓名,<2>号码,<3>分类,<4>邮件地址
[]\b\b");
scanf("%d",&d);
switch(d) { case 1: {
printf("姓
scanf("%s",peo[a].name);}break;
case 2: {
printf("号码:");
scanf("%s",peo[a].num);}break;
case 3: {
printf("分类:");
scanf("%s",peo[a].kind);}break;
case 4: {
printf("邮件地址:");
scanf("%s",peo[a].email);}break;
default:modify();
}
save(b-1);
printf("\n继续修改请输入‘y’\n\n");
printf("\n返回主菜单请任意输入\n\n");
scanf("%c",&c);
switch(c)
{
case 'y':modify();break;
- 10 - 图3-5 修改模块流程图 名:");
default:menu();
}
}
3.2.5删除模块
该模块的功能是先显示所有通信人的信息,显示完后,用户输入要删除通信人的序号,根据序号查找通信人的信息并删除。删除的一般做法是将数据从文件中删除,删除位置后面的记录往前移。具体设计如下:
/***************删除模块***************/
void del(a)
{ int b,i;
b=load();
for(i=a;i<b;i++)
{
strcpy(peo[i].name,peo[i+1].name);
strcpy(peo[i].num,peo[i+1].num);
strcpy(peo[i].kind,peo[i+1].kind);
strcpy(peo[i].email,peo[i+1].email);
}
save(b-2);
menu();
}
3.3公共函数
3.3.1保存函数
形参j控制保存的个数。
程序设计如下:
/***************保存模块***************/
void save(int j)
{
FILE *fp;
- 11 -
int i;
if((fp=fopen("people.txt","wb"))==NULL)
{
printf("\n不能打开文件\n");
return ;
}
for(i=1;i<=j;i++)
if(fwrite(&peo[i],sizeof(struct people),1,fp)!=1 ) printf("\n不能打开文件\n");
fclose(fp);
}
3.3.2加载函数
该函数可以用来加载所有记录,并且可以返回所有记录的个数。程序如下: int load()
{
FILE *fp;
int i;
if((fp=fopen("people.txt","rb"))==NULL)
{
printf("\n不能打开文件\n");
return NULL;
}
for(i=1;!feof(fp);i++)
fread(&peo[i],sizeof(struct people),1,fp);
fclose(fp);
return(i-1);
}
四 运行截图
- 12 -
4.1 主界面
4.2 浏览界面
- 13 -
4.3 查看界面
4.4 增加界面
- 14 -
4.5 修改界面
4.6 删除界面
- 15 -
五 个人心得与总结
这次课程设计是大学以来的第一次课程设计。也是锻炼我们动手能力的一次很好的机会。但是,万事开头难。这次C语言的程序设计,对于我来说是一个挑战。
刚开始几乎不知道该从何下手。后来通过一些简单题目的编写才有了思路。在整个程序的编写过程中在很多地方都遇到了困难。例如,对一些算法的设计有很大漏洞等。后来通过翻阅很多书籍,以及同学的讨论下,在克服了重重的困难后,终于成功的运行了课程设计所要求的程序。这次程序设计是在C语言程序的思想下第一次整体完成的程序设计,所以还有很多的不完美的地方,希望老师予以指出和改正。
这次的程序设计让我受到了很大锻炼,也有了很多感悟。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学到的理论知识与实践相结合起来,从理论中得出结论,将结论辅助与理论,才能真正学到知识并写出有用的程序来为他人服务,更为社会服务,所以提高自己的实际动手能力和独立思考的能力是十分重要的。同时通过这次设计,也让我体验到了编程的的乐趣。
总之,这次的课程设计是一次宝贵的经验,它不仅锻炼了我动手的能力,也锻炼了我克服困难,持之以恒的精神。既收获了知识,又磨练了意志。我想这第一次的课程设计必将成为我人生道路上一段美好的回忆。
参考文献
[1] 张冬梅 刘远兴,c语言课程设计与学习指导,中国铁道出版社,20xx年出版
[2] 谭浩强,c语言设计,清华大学出版社,20xx年第三版
附录
程序源代码
#include<stdio.h>
- 16 -
#include<string.h>
#include<stdlib.h>
#define N peo[i].name,peo[i].num,peo[i].kind,peo[i].email struct people
{
char name[10];
char num[11];
char kind[20];
char email[20];}
peo[15];
int load();
void save(j);
void menu();
void del(a);
/*******************浏览模块*******************/
void scan()
{
int i,b;
b=load();
for(i=1;i<b;i++)
printf("%d> %10s%11s%20s%20s\n\n",i,N);
printf("任意输入返回主菜单");
getchar();
getchar();
menu();
}
/***************查看模块***************/
void browse()
{
int i,a,b;
char c;
b=load();
puts("\t\t***************查看***************\n\n"); puts("\t\t\t\t1.办公类");
puts("\t\t\t\t2.个人类");
puts("\t\t\t\t3.商务类");
printf("请选择需查看的类别(1-3): []\b\b");
scanf("%d",&a);
switch(a)
{ case 1: { printf("办公类有:\n");
printf(" 姓 名 号 码
- 17 - 分 类 邮
件 地 址\n");
for(i=1;i<b;i++)
{
if(strcmp(peo[i].kind,"办公类")==0)
printf("%10s%11s%20s%20s\n",N);
}
}
break;
case 2:{ printf("个人类有:\n");
printf(" 姓 名 号 码 邮 件 地 址\n");
for(i=1;i<b;i++)
{
if(strcmp(peo[i].kind,"个人类")==0) printf("%10s%11s%20s%20s\n",N); }
}break;
case 3: { printf("商务类有:\n");
printf(" 姓 名 号 码 邮 件 地 址\n");
for(i=1;i<b;i++)
{
if(strcmp(peo[i].kind,"商务类")==0) printf("%10s%11s%20s%20s\n",N);
}
}break;
}
printf("\n是否继续查看?(y/n)\n");
getchar();
c=getchar();
switch(c)
{
case 'y':browse();break;
default:menu();}
}
/***************增加模块***************/
void addition()
{int j,b;
puts("\t\t***************增加***************\n\n"); printf("请输入相关信息\n\n");
b=load();
- 18 - 分 类 分 类
if(b>15) { printf("信息已满\n"); menu(); }
printf("姓名:"); scanf("%8s",peo[b].name);
printf("号码:"); scanf("%11s",peo[b].num);
for(j=1;j<b;j++)
{
=0)
{ printf("输入重复\n"); if((strcmp(peo[b].name,peo[j].name)==0)||strcmp(peo[b].num,peo[j].num)=printf("分类:"); scanf("%20s",peo[b].kind); printf("邮件地址:"); scanf("%20s",peo[b].email);
save(b);
del(b);
}
else save(b);
}
getchar();
getchar();
menu();
}
/***************修改模块***************/
void modify()
{ int i,a,b,d;
char c;
puts("\t\t***************修改***************\n\n");
b=load();
for(i=1;i<b;i++)
printf("%d>%10s%11s%20s%20s\n",i,N);
printf("选择你要修改的信息编号: []\b\b");
scanf("%d",&a);
printf("请选择你要修改的项目\n<1>姓名,<2>号码,<3>分类,<4>邮件地址
[]\b\b");
scanf("%d",&d);
switch(d)
{
case 1:
scanf("%s",peo[a].name);}break;
{ printf("姓名:"); - 19 -
case 2: { printf("
scanf("%s",peo[a].num);}break;
case 3: { printf("
scanf("%s",peo[a].kind);}break;
case 4: {
scanf("%s",peo[a].email);}break;
default:modify();
}
save(b-1); 号分 printf("邮码类件地址:"); :"); :");
printf("\n继续修改请输入‘y’\n\n"); printf("\n返回主菜单请任意输入\n\n"); scanf("%c",&c);
switch(c)
{
case 'y':modify();break;
default:menu();
}
}
/***************删除模块***************/ void del(a)
{ int b,i;
b=load();
for(i=a;i<b;i++)
{
strcpy(peo[i].name,peo[i+1].name); strcpy(peo[i].num,peo[i+1].num); strcpy(peo[i].kind,peo[i+1].kind); strcpy(peo[i].email,peo[i+1].email); }
save(b-2);
menu();
}
/***************保存模块***************/ void save(int j)
{
FILE *fp;
int i;
if((fp=fopen("people.txt","wb"))==NULL) {
printf("\n不能打开文件\n");
- 20 -
return NULL;
}
for(i=1;i<=j;i++)
if(fwrite(&peo[i],sizeof(struct people),1,fp)!=1 ) printf("\n不能打开文件\n");
fclose(fp);
}
int load()
{
FILE *fp;
int i;
if((fp=fopen("people.txt","rb"))==NULL)
{
printf("\n不能打开文件\n");
return NULL;
}
for(i=1;!feof(fp);i++)
fread(&peo[i],sizeof(struct people),1,fp);
fclose(fp);
return(i-1);
}
/***************菜单模块***************/
void menu()
{int n,w1,a,i,b;
b=load();
puts("\t\t***************菜单***************\n\n"); puts("\t\t\t\t1.浏览");
puts("\t\t\t\t2.查看");
puts("\t\t\t\t3.增加");
puts("\t\t\t\t4.修改");
puts("\t\t\t\t5.删除");
puts("\t\t\t\t6.退出");
printf("请选择(1-6): ");
scanf("%d",&n);
if(n<1||n>6)
{
w1=1;getchar();}
else w1=0;
while(w1==1);
- 21 -
switch(n)
{
case 1:scan();break;
case 2:browse();break;
case 3:addition();break;
case 4:modify();break;
case 5: {puts("\t\t***************删除***************\n\n");
for(i=1;i<b;i++)
printf("%d> %10s%20s%20s%20s\n",i,N);
printf("选择你要删除的信息的编号: ");
scanf("%d",&a);
del(a);} break;
case 6:exit(0);
}
}
/***************主函数***************/
main()
{
menu();
}
- 22 -