C课设报告多功能上课点名系统.docx
《C课设报告多功能上课点名系统.docx》由会员分享,可在线阅读,更多相关《C课设报告多功能上课点名系统.docx(37页珍藏版)》请在冰点文库上搜索。
C课设报告多功能上课点名系统
C语言课程设计实习报告
专业:
地空学院
学号:
88888888
班级序号:
666666
姓名:
指导教师:
C语言程序设计报告
(实习日期:
2013-12至2014-1)
一、C语言课程设计的目的
高级语言课程设计是学习完《高级语言程序设计》课程后进行的一次全面的综合性上机实验。
其目的在于为同学提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼同学的分析解决实际问题的能力。
提高学生适应实际,实践编程的能力。
二.题目:
自动点名系统
需求分析:
设计一个供教师上课使用的自动点名系统,满足实际点名中的以下功能
1计算机随机选取学生,进行点名。
2可以记录学生是否到课。
3查询历史记录,包括已经点过的学生记录和旷课的学生记录。
4点名时有公平性,任意两个人被点次数差不超过一次(不包括有旷课记录的学生)。
5对旷过课的学生单独点名。
6清除历史记录。
7系统功能清晰、使用方便。
8用文件记录点名、旷课的数据。
三、总体设计
系统由6个模块组成:
连续点名模块:
输入’c’(choose)点一个人,输入’e’(end)返回主菜单,每次点人后输入学生的到课情况(y/n)。
多人点名模块:
根据输入的要点名人数点名,同时记录到课情况,点完后返回主菜单
浏览历史模块:
选择后显示历史记录(点名记录、到课记录)。
点旷课学生模块:
额外点所有有旷到记录的学生,不计入总点名次数,但如果又旷到,则旷到次数加一。
此次上课点名(此次运行程序)已经由前两个模块点到的,不会出现在这个模块。
(即不会出现一个旷到学生被意外记两次的情况)
清除模块:
清除历史记录。
退出模块:
退出程序。
四详细设计
1结构体及函数
学生信息(姓名、学号)存在结构体Student中,各功能由函数实现。
#include
#include
#include
#include
#include
#defineN57
typedefstruct//存储学生信息
{
charnum[9];
charname[7];
}Student;
voidchoose(Student*stu,int*a,int*b,int*c);//chooseastudent
intminimum(int*a);//数组最小值函数
voidfunction(Student*stu,int*a,int*b,int*c);//主菜单函数
voidpickn(Student*stu,int*a,int*b,int*c);//选多个学生的函数
voidpickc(Student*stu,int*a,int*b,int*c);//连续选学生的函数
voidpickhistory(Student*stu,int*b,int*c);//点旷到学生的函数
voidprintrecord(Student*stu,int*a,int*b);//浏览历史函数
voidread(Student*stu);//读取student.txt的函数
voidsaverecord(int*a,int*b);//存储历史记录到sturecord.dat的函数
voidloadrecord(int*a,int*b);//读取文件sturecord.dat的函数
voidclear(int*a,int*b);//清除历史记录函数
voidtitle();//打印标题函数
voidmenu();//打印目录函数
voidborderup();//打印上边界函数
voidborderdown();//打印下边界函数
2主函数
主函数有读取学生信息、读取历史记录、显示菜单、点名、存储信息的功能,全部用函数实现。
intmain()
{
inta[N]={0},b[N]={0},c[N]={0};//a,b,c数组分别存被点次数、
Studentstu[N];//旷课次数、本次上课是否被点
srand((unsigned)time(NULL));
read(stu);
loadrecord(a,b);
title();
menu();
function(stu,a,b,c);
saverecord(a,b);
return0;
}
3各函数设计
(1)存读数据函数
1从student.txt读取学生信息的函数
voidread(Student*stu)
{
FILE*fp;
inti;//circulate
charc,d[5],e,*p;//"c"判断是否为名字的字符,"d"存名字后的空格与回车,"e"存中间的空格
fp=fopen("students.txt","r");//openfile
if(fp==NULL)
{
printf("filedon'texist!
\n");
exit(0);
}
for(i=0;i{
fgets(stu[i].num,9,fp);//学号
e=fgetc(fp);
p=&stu[i].name;//名字
c='\0';
while(c!
='\t')
{
c=fgetc(fp);
if(c!
='\t')
{
*p=c;
p++;
}
else
{
*p='\0';
fgets(d,5,fp);
}
}
}
fclose(fp);
}
2保存点名记录到sturecord.dat的函数
voidsaverecord(int*a,int*b)
{
FILE*fp;
if((fp=fopen("sturecord.dat","wb"))==NULL)
{
printf("can'topenafiletosavedata\n");
exit(0);
}
if(fwrite(a,sizeof(int),N,fp)!
=N)//二进制方式存数据
printf("filewriteerror(arraya)\n");
if(fwrite(b,sizeof(int),N,fp)!
=N)
printf("filewriteerror(arrayb)\n");
fclose(fp);
}
3从sturecord.dat读取点名记录的函数
voidloadrecord(int*a,int*b)
{
FILE*fp;
if((fp=fopen("sturecord.dat","rb"))==NULL)
{
printf("can'topensturecord.data\nrunitagain!
\n\a");
saverecord(a,b);//如果sturecord.data不存在则新建立一个
exit(0);
}
if(fread(a,sizeof(int),N,fp)!
=N)
printf("filereaderror(arraya)\n");
if(fread(b,sizeof(int),N,fp)!
=N)
printf("filereaderror(arrayb)\n");
fclose(fp);}
(2)基本函数
1数组最小值函数
求数组中的最小值,由choose函数调用,choose函数中的随机数r要满足a[r]=miminum(a)才使用。
即每次只点被点过次数最少的学生。
intminimum(int*a)
{
intmi,i;
mi=a[0];
for(i=0;i{
if(mi>a[i])
mi=a[i];
}
return(mi);
}
2点名函数
Choose函数可以用随机数r从stu[N]结构体中随机选择一个再输出相应学生信息,a[N]记录下被点学生(a[r]++;),之后可以用b[N]记录学生是否到课(y/n)。
c[N]记录此次课(此次运行程序)的点名,不保存到sturecord.dat,用于防止此次上课点名已经由随机点名模块(pickn,pickc)点到的,不会出现在旷到学生点名模块(pickhistory)。
将在pickc、pickn函数中调用。
voidchoose(Student*stu,int*a,int*b,int*c)
{
intr;
charyon,e;//’yon’yesorno,’e’接收回车
do
{
r=rand()%N;//r为0到N-1的随机数
}
while(a[r]!
=minimum(a));
a[r]++;//记录下被点学生
c[r]++;
printf("%s\n",stu[r].name);
printf("%s\n",stu[r].num);
printf("\nEnter'y'or'n'torecordattendance:
[]\b\b");
yon=getchar();
e=getchar();//接收回车
putchar('\n');
if(yon=='n')
{
b[r]++;//记录旷到
printf("****************************\n");
printf("theabsencehasbeensaved.\n");
printf("****************************\n\n");
}
}
(3)功能模块
1连续点名函数
输入’c’点名,直到输入’e’时结束
voidpickc(Student*stu,int*a,int*b,int*c)//参数在调用chooses时使用
{
charcoe='c',e;//’coe’控制点名或是结束,'e'接收回车
borderup();//打印边界,每个功能函数开始结尾都有
//使程序运行时显得清晰
while(coe=='c')
{
printf("Enter'c'tochoose,enter'e'toend:
[]\b\b");
coe=getchar();
e=getchar();
if(coe=='c')
{
putchar('\n');
choose(stu,a,b,c);
}
}
borderdown();
}
2点n人函数
输入要点的人数点名
voidpickn(Student*stu,int*a,int*b,int*c)
{
intn,i,e;
borderup();
printf("Howmanystudentsdoyouwanttocheck?
[]\b\b");
scanf("%d",&n);
e=getchar();
printf("\n");
for(i=0;ichoose(stu,a,b,c);
borderdown();
}
3浏览历史模块
显示被点情况、旷到情况
voidprintrecord(Student*stu,int*a,int*b)
{
inti;
borderup();
printf("namenumberofbeingpickednumberofabsencenumber\n");
for(i=0;i{printf("%6s%d%d%s\n",stu[i].name,a[i],b[i],stu[i].num);
}
borderdown();
}
4点旷到学生模块
点所有有旷到记录的学生,完成显示’finish’。
因为不随机,不调用choose。
voidpickhistory(Student*stu,int*b,int*c)
{
inti,yon,e;
borderup();
for(i=0;iif(b[i]!
=0&&c[i]==0)//有旷到记录且这节课还没点过的
{//后半段与choose函数一致
printf("%s\n",stu[i].name);
printf("%s\n",stu[i].num);
printf("\nEnter'y'or'n'torecordattendance:
[]\b\b");
yon=getchar();
e=getchar();
putchar('\n');
if(yon=='n')
{
b[i]++;
printf("****************************\n");
printf("theabsencehasbeensaved.\n");
printf("****************************\n\n");
}
}
printf("finish!
\n");
borderdown();
}
5清除模块
用saverecord函数使历史记录sturecord.dat恢复到原始值。
voidclear(int*a,int*b)
{
inti;
for(i=0;i{
a[i]=0;
b[i]=0;
}
saverecord(a,b);
printf("Allrecordhasbeenclearsuccessfully.\n\n\n");
}
删除模块:
用户输入要删除的信息,如输入歌曲名,根据歌曲名找到其他记录并删除。
[程序]
voiddelete()
{
intj,v,c;
charw[20];
FILE*fp;
printf("Pleaseinputthesong'namewhichyouwanttodelete:
");
scanf("%s",w);
fp=fopen("data.txt","rb");
for(j=0;j<100;j++)
{
if(fread(&dan[j],sizeof(structsystem),1,fp)!
=1)break;
}
v=j;
for(j=0;j{
if(strcmp(w,dan[j].name)==0)
c=j;
}
fclose(fp);
fp=fopen("data.txt","wb");
for(j=0;j{
if(j!
=c)
fwrite(&dan[j],sizeof(structsystem),1,fp);
}
fclose(fp);
printf("DeleteOK!
\n");
i--;
}
(4)菜单函数
菜单函数调用五个功能函数实现菜单的功能,return回到主函数存储数据后程序结束。
voidfunction(Student*stu,int*a,int*b,int*c)
{
charf,e;//'f'存选择'e'存回车
while
(1)
{
printf("Enterfunctionnumber<1-6>:
[]\b\b");
scanf("%c",&f);
e=getchar();
switch(f)
{
case'1':
pickc(stu,a,b,c);break;
case'2':
pickn(stu,a,b,c);break;
case'3':
printrecord(stu,a,b);break;
case'4':
pickhistory(stu,b,c);break;
case'5':
clear(a,b);break;
case'6':
printf("\n");return;break;
default:
menu();//menu函数打印功能及对应数字
}
}
}
}
(5)打印界面函数
voidtitle()
{printf("****************************************************************\n");
printf("**\n");
printf("*ROLLCALLSYSTEM*\n");
printf("**\n");
printf("***************************************************************\n");
}
voidmenu()
{
borderup();
printf("Instruction:
\n");
printf("1:
chooseonestudenteachtime\n");
printf("2:
chooseseveralstudents\n");
printf("3:
openhistoryrecord\n");
printf("4:
choosestudentswhohaveabsencerecored\n");
printf("5:
clearhistory\n");
printf("6:
exit\n");
printf("(default:
showthisinstructionagain)\n");
borderdown();
}
voidborderup()
{
printf("-----------------------------------------------------------\n");
}
voidborderdown()
{
printf("-----------------------------------------------------------\n\n\n\n");
}
程序的流程图如上
五上机操作
1主菜单函数
2连续点名功能
3多人点名功能
4浏览历史模块.
5点旷到学生模块
6.删除记录模块
7退出模块
学习心得
这次C语言课程设计让我学到了很多东西,有了自己设计程序、编写程序的经验,可以自己解决编程过程中的遇到的困难与问题。
一开始随机数不会写,到网上查阅了资料学会了随机数需要的函数。
文件的读写也碰到了很多问题,编写从student.txt读信息到结构体的函数用了很长时间,刚写的时候不是字符数目不对,就是对fgets函数不熟悉(不知道碰到回车符时自动结束)。
在读写信息存到文件sturecord.dat时,用二进制存取,但在打开与读取时没用’wb’’rb’因而碰到了很奇怪的问题,做了很多检查又看了书后才发现问题。
有一次没有改完错误就关了机,过了几天才又编写,结果打文件编译有问题时完全忘了在哪有问题,提示有8个错误。
然后只能隔离各个函数检查,不久发现了问题所在。
有时候改了很多地方才又重新编译,结果错了很多处,找了一下找不到问题,又忘记改了哪里,让事情变得很麻烦。
这让我知道以后大幅更改前应先另存文件或将改的地方做标记。
当运行效果更预计不一样时,我学会了从运行情况分析代码不完善的地方。
例如,各功能函数编好了后,运行时发现依次运行123456功能时3不正常,显示error(表示输入了1-6以外的数),之后456也error,但第一次运行3、4、5或6又正常。
之后我分别运行11、22、33、44、55、66。
发现只有连续用两次2功能时有问提,并且之后再用其他的也有问题。
于是我确定是2的函数有问题,并且是输入的问题,在之后运行其他功能时是把回车传了进去。
检查后发现2中确实忘记接收回车。
这次编程让我学到了不少知识,更让我意识到了自己动手实践的重要性,有耐心、毅力才能把事情做好。
六、算法和系统的优缺点
系统的优点是简洁、清晰,每次次用完一个功能屏幕上的内容都在一个框内,显得有条理。
点名的信息以文件储存,便于调用。
改进思路:
在删除模块中加入可选择的删除模式,达到如查找模块一样的可选择模式删除。
另外在退出系统模块中加入返回主菜单功能。
七:
原代码(附录)
#include
#include
#include
#include
inti=0;
structsystem
{
charauthor[20];
charsinger[20];
chartime[20];
charname[20];
}dan[100];
voidenter()
{
intj;
charc[2];
FILE*fp;
if((fp=fopen("data.txt","w"))==NULL)
{
printf("Cannotopenthefile!
\n");
exit(0);
}
for(j=0;j
{
fwrite(&dan[j],sizeof(structsystem),1,fp);
}
while
(1)
{
printf("Pleaseinputtheauthor:
\n");
scanf("%s",dan[i].author);
printf("Pleaseinputthesong'sname:
\n");
scanf("%s",dan[i].name);
printf("Pleaseinputthesinger:
\n");
scanf("%s",dan[i].singer);
printf("Pleaseinputtheoutday:
\n");
scanf("%s",dan[i].time);
if(fwrite(&dan[i