《编程实习》报告
学院:xxxxxx
专业:xxxxxxx
班级: xxxxxxx
学号: xxxxxxx
姓名: xxx
导师: xxxxxxx
20##年 7 月7日
通讯录管理系统
1设计题目的内容、任务、具体要求及系统功能需求分析
内容:通过计算机对数据文件的存储和读取,设计并实现一个有名片的输入、输出、添加、查询、删除和修改等功能的通讯录管理工具软件,管理用户通信联系人的名片信息。名片包含的主要信息有:姓名、职务、单位、固定电话、手机、E-Mail、QQ、MSN、备注等。
具体要求:
1. 将名片信息存放在二进制文件“Cards.dat”中。文件头部信息包含用户注册号(8位)和名片数量(小于200)。用户注册号采用设计者的学号。每个名片的信息存为一条记录,数据项及数据项的长度根据需求和常理自行设计。第一次运行时,名片文件才产生,此时需要输入注册号。
2. 在查询时,可以显示所有的名片信息。
3. 具有添加新名片功能。
4. 具有删除功能。对查询的结果,可以选择名片(输入姓名)来删除该名片。
5. 具有修改功能。对查询的结果,可以选择名片(输入姓名)来修改该名片。修改时逐项修改
6. 系统启动时,如果不存在名片文件则视为首次运行,否则,需自动加载名片信息,并显示“欢迎使用本系统!!!”的信息,其中“密码是自设密码”。
7. 要求在人机交互时,系统显示的信息列表整齐、清晰,并有必要的提示。
2总体设计思路
本系统首先设计出了主函数,然后根据需要实现的功能分别设计显示、删除、查询、修改、添加功能的子函数。在显示的函数设计过程中首先运行用文件读取等必要的知识通过把文件的内容读取到内存然后打印出来。删除函数的设计是首先从文件内找到要删除的人,然后通过写一个实现删除目的的FOR循环将该人想哦那个内存里删除,然后再用写的方式打开文件,将内存中的信息写入文件,实现删除。查找也是先打开文件,用一个字符串对比额方式找出用户要查找的人,然后显示出来。修改也答题和删除相同,添加也是差不多的,从而实现相关功能。
系统功能模块图:
总的流程图:
3具体设计
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 200
/* 定义结构体,并取别名为SUBS */
typedef struct subs
{
char name[31];
char post[51];
char dept[51];
char phone[8];
char telephone[8];
char EMail[25];
char QQ[8];
char MSN[8];
char Note[51];
}SUBS;
/* 本程序将要用到的函数原型 */
int chcode();
void addSub();/* 添加用户 */
void searchSub(int a);/* 查询用户 */
void modSub();/* 修改用户 */
void delSub();/* 删除用户 */
int rFile(SUBS *);/* 读文件,参数为要读写到文件中的结构体指针,成功返回读的记录条数,失败返回0 */
int wFile(SUBS *,int);/* 写文件,参数为要读写到文件中的结构体指针和要写的记录条数*/
int sStruct(SUBS *s, int);/* 结构体排序,参数为要排序的结构体指针,成功返回1 */
void vewSub();/* 显示所有文件中的记录 */
int checkError(SUBS *);/* 检查输入的用户是否有错,没有错返回0 */
void main()
{
if(!chcode())
{exit(0);
}
char ch;
int i = 0;
do /*显示运行时人机界面,提供菜单选择,等待用户输入功能键*/
{
printf("\t\t\t\tTELEPHONE DIRECTORY SYSTEM\n");
printf("\t1. Add new subscriber details\n");
printf("\t2. Modify existing subscriber details\n");
printf("\t3. Delete existing subscriber details\n");
printf("\t4. Display subscriber details based on subscriber name\n");
printf("\t5. View Directory\n");
printf("\t6. Quit\n");
printf("Please Enter Your Choice:");
scanf(" %c",&ch);
switch(ch)
{
case '1':
addSub();
break;
case '2':
modSub();
break;
case '3':
delSub();
break;
case '4':
searchSub(1);
break;
case '5':
vewSub();
break;
case '6':
exit(0);
break;
default:
printf("Please Enter Choice between 1 and 6\n");
break;
}
}while(1);
}
/*密码检查*/
int chcode()
{char a[]={'0','8','9','3','1','4','0','4'},b[9];/*密码为08931404*/
int i;
printf("请输入密码:");
scanf("%s",b);
for(i=0;i<=7;++i)
if(a[i]!=b[i])
{printf("您无权使用本系统!!!\n");
printf("\n\n按任意键离开!");
//getchar();
//getchar();
return 0;
}
else
if(i==7)
{printf("欢迎使用本系统!!!\n");
return 1;
}
}
/* 增加订户 */
void addSub()
{
SUBS sub[N];
int i=0;
i=rFile(sub);
if(i==N)/* 判断记录是否写满 */
{
printf("Recorder is Full.");
return;
}
do
{
printf("\t\t\tADD NEW SUBSCRIBER DETAILS\n\n");
printf("\nEnter Subcriber name(upto 30 chars.):");
scanf("%s",sub[i].name);
printf("\nEnter Subcriber post(upto 50 chars.):");
scanf("%s",sub[i].post);
printf("\nEnter Subcriber dept(upto 50 chars.):");
scanf("%s",sub[i].dept);
printf("\nEnter phone number:");
scanf("%s",sub[i].phone);
printf("\nEnter telephone number:");
scanf("%s",sub[i].telephone);
printf("\nEnter EMail:");
scanf("%s",sub[i].EMail);
printf("\nEnter QQ:");
scanf("%s",sub[i].QQ);
printf("\nEnter MSN:");
scanf("%s",sub[i].MSN);
printf("\nEnter Note(upto 100 char.):");
scanf("%s",sub[i].Note);
}while(checkError(&sub[i]));/* 检查错误,直到输入完全符合要求 */
i++;
sStruct(sub,i);
printf("Subscriber details have been added %d\n", wFile(sub,i));
}
/* 查询订户,给一个参数,如果为1可按名查 */
void searchSub(int a)
{
SUBS sub[N];
char temp[30];
int i,j;
i=rFile(sub);/* 读文件 */
switch(a)
{
case 1:
printf("Enter Subscriber name:");
scanf("%s",temp);
for(j=0;j<i;j++)
{ if(strcmp(temp, sub[j].name)==0)
{
printf("\t\tREQUESTED SUBSCRIBER DETAILS\n");
printf("Name:%s\nPost:%s\nDept:%s\nPhone Number:%s\nTelephone Number:%s\nEMail:%s\nQQ:%s\nMSN:%s\nNote:%s\n\n",sub[j].name,sub[j].post,sub[j].dept,sub[j].phone,sub[j].telephone,sub[j].EMail,sub[j].QQ,sub[j].MSN,sub[j].Note);
break;
}
}
if(j==i)
{
printf("Cannot find!\n");
break;
}
//default:
//printf("Please Enter 1 to search with name!\n");
//break;
}
}
/* 删除订户 */
void delSub()
{
SUBS sub[N];
int i=0,j;
char temp[30];
i=rFile(sub);
printf("\t\tDELETE SUBSCRIBER DETAILS\n");
printf("Enter Subscriber name (upto 30 chars.):");
scanf(" %s",temp);
for(j=0;j<=i;j++)/* 查找需要删除的记录 */
{
if(strcmp(temp,sub[j].name)==0)
{
printf("\t\tREQUESTED SUBSCRIBER DETAILS\n");
printf("Name:%s\nPost:%s\nDept:%s\nPhone Number:%s\nTelephone Number:%s\nEMail:%s\nQQ:%s\nMSN:%s\nNote:%s\n\n",sub[j].name,sub[j].post,sub[j].dept,sub[j].phone,sub[j].telephone,sub[j].EMail,sub[j].QQ,sub[j].MSN,sub[j].Note);
for( ;j<i;j++)/* 删除订户 */
sub[j]=sub[j+1];
i--;
wFile(sub,i);
printf("Delete successfully!\n");
return;
}
}
printf("cannot find!");
}
/* 修改订户 */
void modSub()
{
SUBS sub[N];
char temp[30];
int i=0,j;
printf("\t\tMODIFY SUBSCRIBER DETAILS\n");
printf("Enter Subscriber name (upto 30 chars.):");
scanf("%s",temp);
printf("temp=%s\n",temp);
i=rFile(sub);/* 读文件 */
for(j=0;j<i;j++)
{
if(strcmp(sub[j].name,temp)==0)/* 找出名字相同的订户并进行修改 */
{
printf("\t\tRECORD TO BE MODIFIED\n");
printf("Name:%s\nPost:%s\nDept:%s\nPhone Number:%s\nTelephone Number:%s\nEMail:%s\nQQ:%s\nMSN:%s\nNote:%s\n\n",sub[j].name,sub[j].post,sub[j].dept,sub[j].phone,sub[j].telephone,sub[j].EMail,sub[j].QQ,sub[j].MSN,sub[j].Note);
do
{
printf("\nj=%d",j);
printf("\t\t\tMODIFY THE SUBSCRIBER DETAILS\n\n");
printf("\nEnter Subcriber name(upto 30 chars.):");
scanf("%s",sub[j].name);
printf("\nEnter Subcriber post(upto 50 chars.):");
scanf("%s",sub[j].post);
printf("\nEnter Subcriber dept(upto 50 chars.):");
scanf("%s",sub[j].dept);
printf("\nEnter phone number:");
scanf("%s",sub[j].phone);
printf("\nEnter telephone number:");
scanf("%s",sub[j].telephone);
printf("\nEnter EMail:");
scanf("%s",sub[j].EMail);
printf("\nEnter QQ:");
scanf("%s",sub[j].QQ);
printf("\nEnter MSN:");
scanf("%s",sub[j].MSN);
printf("\nEnter Note(upto 100 char.):");
scanf("%s",sub[j].Note);
}while(checkError(&sub[j]));/* 检查错误,直到输入完全符合要求 */
printf("Subscriber details have been modified\n");
break;
}
}
if(j==i)
{
printf("Cannot find subscriber\n");
}
else
{
printf("mod:Name:%s\nPost:%s\nDept:%s\nPhone Number:%s\nTelephone Number:%s\nEMail:%s\nQQ:%s\nMSN:%s\nNote:%s\n\n",sub[j].name,sub[j].post,sub[j].dept,sub[j].phone,sub[j].telephone,sub[j].EMail,sub[j].QQ,sub[j].MSN,sub[j].Note);
sStruct(sub,i);
wFile(sub,i);
}
}
/* 读文件,参数为要读写到文件中的结构体指针,成功返回读出的记录条数 */
int rFile(SUBS *s)
{
FILE *fp;
int i=0;
if((fp=fopen("Cards.dat","rb"))==NULL)
{
//printf("cannot open file!\n");
/* getch(); */
return 0;
}
else
{
rewind(fp);
while(!feof(fp))
{
//fflush(fp);
fread(&s[i],sizeof(SUBS),1,fp);
i++;
//fread(&s[i],sizeof(SUBS),1,fp);
//i++;
}
i--;//读取到最后一条时,弥补i++
}
fclose(fp);
return i;
}
/* 写文件,参数为要写到文件中的结构体指针,记录条数。成功返回所写记录的条数 */
int wFile(SUBS *s,int i)
{
FILE *fp;
int j;
if((fp=fopen("Cards.dat","wb"))==NULL)
{
//printf("cannot open file!\n");
/* getch(); */
return 0;
}
else
{
for(j=0;j<i;j++)
{
fflush(fp);
fwrite(&s[j],sizeof(SUBS),1,fp);
}
}
fclose(fp);
//return j; mod
return i;
}
/* 结构体排序,参数为要排序的结构体指针,记录条数。成功返回排序记录条数 */
int sStruct(SUBS *s, int i)
{
SUBS temp;
int j,m;
for(j=0;j<i-1;j++)/* 排序 */
for(m=j+1;m<i;m++)
if(strcmp(s[j].name,s[m].name)>0)
{
temp=s[j];
s[j]=s[m];
s[m]=temp;
}
return i;
}
/* 显示所有文件中的记录 */
void vewSub()
{
SUBS sub[N];
int i=0,j;/* 用于显示记录条数的变量 */
i=rFile(sub);
printf("i=%d",i);
getchar();
getchar();
for(j=0;j<i;j++)
{
printf("Record %d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",j+1,sub[j].name,sub[j].post,sub[j].dept,sub[j].phone,sub[j].telephone,sub[j].EMail,sub[j].QQ,sub[j].MSN,sub[j].Note);
}
}
/* 检查输入的订户是否有错,传入需要检测的结构体指针,有错返回1,没有错返回0 */
int checkError(SUBS *s)
{
if( strlen(s->name)==0||strlen(s->name)>30||
strlen(s->post)==0||strlen(s->post)>50||
strlen(s->dept)==0||strlen(s->dept)>50||
strlen(s->phone)!=7||strcmp("4000000",s->phone)>0||
strcmp("4999999",s->phone)<0||
strlen(s->telephone)!=7||strcmp("4000000",s->telephone)>0||
strcmp("4999999",s->telephone)<0||
strlen(s->EMail)==0||strlen(s->EMail)>24||
strlen(s->QQ)==0||strlen(s->QQ)>7||
strlen(s->MSN)==0||strlen(s->MSN)>7||
strlen(s->Note)==0||strlen(s->Note)>50)
{
printf("Your Enter is error,please reEnter:\n");
printf("Note:Subscriber telephone number or phone number must be between 4000000 and 4999999!!\n");
return 1;
}
return 0;
}
4程序设计中的数据设计
软件中的结构体和结构体数组,如:
/* 定义结构体,并取别名为SUBS */
typedef struct subs
{
char name[31];
char post[51];
char dept[51];
char phone[8];
char telephone[8];
char EMail[25];
char QQ[8];
char MSN[8];
char Note[51];
}SUBS;
对用户的信息进行保存,它们都以二进制的形式读写
其中char name[31];
char post[51];
char dept[51];
char phone[8];
char telephone[8];
char EMail[25];
char QQ[8];
char MSN[8];
char Note[51];
分别对姓名,职务,单位,固定电话,手机,Email,QQ,MSN,备注进行存储
在子函数中还使用了exit()、fclose()等库函数
还运用了头文件:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
其中还使用了大量的子函数
通过对这些资源的合理利用使系统初步实现了通讯了管理系统的基本功能
5程序调试与运行
首次登入时,系统会提示“请输入密码”,如果输入密码是正确的,则系统显示“欢迎使用本系统!!!”如果输入密码是错误的,则显示“您无权使用本系统”,按任意键离开。在密码正确的前提下,有1-6个选项供选择。例如,选择1,是为添加联系人,然后按回车,根据提示进行添加各种信息,每填完一项,就按回车进行下一项填写。必须注意的是,在填写固定电话,手机时,应填写4000000-4999999之间,否则程序视不能成功添加;选择2,是为修改联系人,通过输入联系人姓名来逐项修改;选择3为删除联系人,通过名字删除;选择4为通过姓名查找,只需输入姓名进行查找;选择5为显示通讯录中的联系人个数;6则为对出程序。
6心得与体会
本次编程实习是我进大学一来第一次设计完成的大程序。通过自己上机调试运行,发现和解决问题,我意识到了我的很多不足之处。以前没有掌握好的知识在这次实习中彻底暴露出来了。在经过自己的不断努力和探索,以及同学们和老师的帮助之下,终于有所收获,在经过差不多2周的时间,完成了本次实习任务。可能其中还有不足的地方。但我相信,在今后的自我学习中能够解决好它们。总的来说,通过这次编程设计,我还是收获很多的。因为不仅多C++的操作有了进一步的熟悉和掌握,还了解了程序设计的设计思想,结构构想,书写格式和注释格式。,同时强化了过去的只是,巩固了一些知识。
当我拿到题目的时候,我开始是不知所措的,幸好老师有个模板给我们参考。一直以来,我是喜欢看程序读一些。看着那程序,就觉得大致的模板就心里有数了。通过画出功能流程图,再者是根据程序调试,慢慢的就有了方向。在调试过程中,碰到了很多问题。首先是运行前的密码输入。根据参考文献中的程序,将密码检查编入程序中。然后是检查程序中多余的项,发现删除了“读文件”中的几项多余的部分,以及将程序“写文件”部分中的,return j改为return i,就将模板文件中的乱码给解决掉了。还有在老师的帮忙下,将删除文件部分修改的更加完善。总之,这次短学期的学习是一次不错的经历