c语言课程设计之实验设备管理系统.docx
《c语言课程设计之实验设备管理系统.docx》由会员分享,可在线阅读,更多相关《c语言课程设计之实验设备管理系统.docx(23页珍藏版)》请在冰豆网上搜索。
c语言课程设计之实验设备管理系统
目录.............................................................................................................................-1-
一设计目的.................................................................................................................-2-
二课程设计的内容.....................................................................................................-2-
三课程设计的要求与数据.........................................................................................-2-
四课程设计应完成的工作.........................................................................................-2-
五总体设计(包含几大功能模块——流程图).....................................................-2-
六详细设计(各功能模块的具体实现算法——流程图).....................................-3-
七调试分析(包含各模块的测试用例,及测试结果)..........................................-8-
八总结.........................................................................................................................-17-
九成员设计内容.........................................................................................................-17-
十参考资料.................................................................................................................-17-
一:
设计目的
练习与巩固《C语言程序设计》)理论知识,通过实践检验和提高实际能力,进一步培养自己综合分析问题和解决问题的能力。
掌握运用C语言独立地编写、调试应用程序和进行其它相关设计的技能。
二:
课程设计内容
实验室设备管理系统
三:
课程设计要求
实验设备信息包括:
设备编号,设备种类(如:
微机、打印机、扫描仪等等),设
备名称,设备价格,设备购入日期,是否报废,报废日期等。
主要功能:
[1]完成对设备信息的录入函数
[2]完成修改某个设备信息的函数
[3]根据给定信息对设备进行分类统计
[4]设备的破损耗费和遗损处理(删除某个指定设备)
[5]设备的查询
四:
课程设计应完成的工作
(1)编写算法;
(2)算法测试,并有具体的测试结果和结果分析;
(3)撰写课程设计报告。
内容包括:
1)封面扉页
2)设计任务书
3)目录
4)总体设计方案(包括流程图)
5)使用说明及运行实例(包括界面)
6)成员设计内容简介
7)项目源程序代码(注意注释的使用)
8)指导教师评语
五总体设计(包含几大功能模块)
1、功能1:
打开一个设备信息文件,并读取
2、功能2:
添加新的设备内容并保存
3、功能3:
统计设备数量
4、功能4:
查找符合条件的设备及其数量并将其显示出来
5、功能5:
对设备信息按条件进行分类排序
6、功能6:
修改设备信息
7、功能7:
删除某条设备记录
8、功能8:
显示内容
六:
详细设计
图1系统框图
图2菜单图
思路:
使用文件的方式读取和写入设备信息,文件保存在一个固定路径,并以固定的名称进行读取和修改,因此对文件名和路径进行宏定义。
设备内容根据需求定义了结构体如下:
structinstrument{
charid[10],kind[10],name[10],price[10],in_date[10],reject[10],out_date[10];
}
结构体内元素分别为编号、种类、名称、价格、购入日期、是否报废、报废期限等,为了方便操作均以字符串的形式进行保存。
以下为程序重要功能图:
(1)对文件的操作
FILE*fp;
fp=fopen(,"a");
"a"以附加的方式打开只写文件。
若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,这种用法是为了主要是用于添加新的信息在文件末端,用在添加设备函数内。
fp=fopen(,"r");
以只读方式打开,用在需要读取设备信息的函数的内。
fp=fopen(,"w");
以只写形式打开,用于需要改动信息并保存的函数
图3文件操作流程图
以上是对文件的读取,读取完成后便可以进行内容的操作。
(2)添加函数additem()
fp=fopen(,"a");//"a"以附加的方式打开只写文件。
若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾.
图4添加操作流程图
。
(3)统计文件内信息量load()
该函数用于统计文件内设备数量以便于读取,当文件内设备读取到空行(检测到EOF)返回行数。
流程图:
图5文件尾检测流程图
(4)查找check()
在读取出文件内容后比对条件进行查找,如果符合条件输出,由于内容均以字符串的方式保存,因此便于查找。
图6查找操作流程图
(5)分类sort()
按某种条目进行分类也是需要通过查找相同,但不同的是条目的具体内容是不确定的,只是把条目内容相同的部分进行排序使其归类在一起,使用了冒泡排序法。
由于是使用字符串,所以排序的依据是根据ASCII码顺序。
(6)修改modify()
原理:
在读取文件保存在内存后,按行选择修改某一行即修改结构体数组的某一元素,在将其写入到文件中。
图7修改操作流程图
(7)删除delect()
读取文件内容,但读写时跳过需要删除的行不读,然后把读取出的内容重新写入文件
图8删除操作流程图
(8)显示数据函数show()
文件
读取
显示
关闭
图9显示操作流程图
七:
调试分析
7.1源程序及注释
以下为程序重要功能函数:
(1)对文件的操作(使用文件流操作相关函数)
FILE*fp;
fp=fopen(,"a");
"a"以附加的方式打开只写文件。
若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,这种用法是为了主要是用于添加新的信息在文件末端,用在添加设备函数内。
fp=fopen(,"r");
以只读方式打开,用在需要读取设备信息的函数的内。
fp=fopen(,"w");
以只写形式打开,用于需要改动信息并保存的函数内。
读取文件(部分程序)(对行数据部分使用可以连续分割字符串strtok函数,还有字符串复制函数memccpy)
读取文件用于显示和修改
charmystring2[100],*t={"\;"};i=load();//读取文件数量
if(i==-1||i==0)//如果文件打开失败或文件内没有内容
{printf("can'topennodata");
return;}
for(n=0;n
fgets(mystring2,100,fp);//按行的方式一行行显示文件
}
该程序段出现过的问题:
由于统计上面统计文件行数的函数的问题导致漏读。
以上程序段只是按行读取文件,并没有对没一行文件内容,如编号、种类等区分出来,上面适用于单纯的显示设备信息(show()函数)。
在要对文件信息进行改动的函数内,还需要把行内容按结构体内容进行读取,加上以下函数段,采用了字符函数对行内容进行分割和复制即可。
if(n!
=0){
memccpy(a,strtok(mystring2,t),'\;',10);
memccpy(eup[n].id,strtok(NULL,t),NULL,10);//将行内容以"\;"分割,并把分割返回的值以10个字节形式返回
}
else{
memccpy(eup[n].id,strtok(mystring2,t),'\;',10);
}
memccpy(eup[n].kind,strtok(NULL,t),NULL,10);
memccpy(eup[n].name,strtok(NULL,t),NULL,10);
memccpy(eup[n].price,strtok(NULL,t),NULL,10);
memccpy(eup[n].in_date,strtok(NULL,t),NULL,10);
memccpy(eup[n].reject,strtok(NULL,t),NULL,10);
memccpy(eup[n].out_date,strtok(NULL,t),NULL,10);
}
fclose(fp);
以上是对文件的读取,读取完成后便可以进行内容的操作。
问题:
起初因为要求里没要求用文件方式保存所以没有用文件写了一个程序,但后来写了1/3想了想应该不会那么简单就改用文件,结果浪费了很多时间。
但用了文件的方式后发现有些函数写起来更加简单。
例如在删除函数,如果不用文件而将数据保存在内存中时要删除就得对链表进行修改,而改用文件后只需要把跳过删除的数据把数据重新写入文件。
此外,用了文件的方式后不用处理链表这样困难的结构。
(2)添加函数additem()
FILE*fp;//打开文件
fp=fopen(,"a");//"a"以附加的方式打开只写文件。
若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾
printf("请输入编号:
");
scanf("%s",into.id);
printf("\n");
printf("请输入种类:
");
scanf("%s",into.kind);
printf("\n");
printf("请输入名称:
");
scanf("%s",into.name);
printf("\n");
j=0;
do{
printf("请输入价格:
");
scanf("%s",into.price);
printf("\n");
j=isnumber(into.price);
if(j==0)printf("输入错误\n");
}while(j==0);
j=0;
do{
printf("请输入购入日期:
");
scanf("%s",into.in_date);
printf("\n");
j=isnumber(into.in_date);
if(j==0)printf("输入错误\n");
}while(j==0);
printf("是否报废(写Y或N):
");
scanf("%s",into.reject);
j=0;
do{
printf("请输入报废期限:
");
scanf("%s",into.out_date);
printf("\n");
j=isnumber(into.out_date);
if(j==0)printf("输入错误\n");
}while(j==0);
if(load()!
=0)
fprintf(fp,"\r");
fprintf(fp,"\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\r\n",into.id,into.kind,into.name,into.price,into.in_date,into.reject,into.out_date);
fclose(fp);
printf("\n\n\t添加成功\n\n");
函数出现过的问题:
由于\n,\r\n的分不清一开始每一行的结尾使用\n的,导致下面读取时会少一行,通过网络查阅资料后,在第一行前加\r,每行末尾加\r\n解决了问题。
(3)统计文件内信息量load()
该函数用于统计文件内设备数量以便于读取,当文件内设备读取到空行(检测到EOF)返回行数。
intload(charfile[]){
charc;
inth=0;
FILE*fp;
fp=fopen(file,"r");
if(fp==NULL)
return-1;//表示文件打开错误
fseek(fp,0,0);
while((c=fgetc(fp))!
=EOF)
{
if(c=='\n')
h++;
else
{
if(c==EOF)
{
h++;
break;
}
}
}
fclose(fp);
returnh;
}
该函数出现过的问题:
起初有时无法正确读取文件,原因是在additem这个函数里添加的格式不对,把additem这个函数改后就可以了。
(4)查找check()
在读取出文件内容后比对条件进行查找,如果符合条件输出,由于内容均以字符串的方式保存,因此便于查找。
if(i==1)//i为输入的查找条目
{for(n=0,k=0;nif(strcmp(q,eup[n].id)==0)//=0,符合条件并输入
{
printf("在文件中第%d行\n",n);
printf(“__________________________________________________\n”);
printf("%s\;%s\;%s\;%s\;%s\;%s\;%s\;\n",eup[n].id,eup[n].kind,eup[n].name,eup[n].price,eup[n].in_date,eup[n].reject,eup[n].out_date);
k++;//这个是用来统计符合条件设备的数量的
}
}
if(k==0)
printf("hasnodata\n");
(5)分类sort()
按某种条目进行分类也是需要通过查找相同,但不同的是条目的具体内容是不确定的,只是把条目内容相同的部分进行排序使其归类在一起,使用了冒泡排序法。
由于是使用字符串,所以排序的依据是根据ASCII码顺序。
if(c==3)
for(n=0;n{
for(k=0;k{
if(strcmp(eup[k].reject,eup[k+1].reject)<0){
exchange=eup[k];
eup[k]=eup[k+1];
eup[k+1]=exchange;
}
}
}
(6)修改modify()
原理:
在读取文件保存在内存后,按行选择修改某一行即修改结构体数组的某一元素,在将其写入到文件中。
printf("\n输入你要修改的设备的行数!
\n\n实验设备的行数:
");
scanf("%d",&n);
printf("\n找到要修改的设备!
\n");
b=2;
do{
printf("\n请输入你要修改的1:
编号2:
种类3:
名称4:
价格5:
购入日期6:
报废7:
报废期限:
\n");
scanf("%d",&c);
switch(c){
case1:
printf("请输入编号:
");scanf("%s",eup[n].id);printf("\n");break;
case2:
printf("请输入种类:
");scanf("%s",eup[n].kind);printf("\n");break;
case3:
printf("请输入名称:
");scanf("%s",eup[n].name);printf("\n");break;
case4:
printf("请输入价格:
");scanf("%s",eup[n].price);printf("\n");break;
case5:
f=0;do{
printf("请输入购入日期:
");
scanf("%s",eup[n].in_date);
printf("\n");
f=isnumber(eup[n].in_date);
if(f==0)printf("输入错误\n");
}while(f==0);
printf("\n");
break;
case6:
printf("是否报废(写Y或N):
");scanf("%s",eup[n].reject);printf("\n");break;
case7:
f=0;do{
printf("请输入报废期限:
");
scanf("%s",eup[n].out_date);
printf("\n");
f=isnumber(eup[n].out_date);
if(f==0)printf("输入错误\n");
}while(f==0);
printf("\n");
break;
default:
break;
}
printf("接下来1:
对该设备信息修改完成2:
还需要对该设备进行修改\n");
scanf("%d",&b);
while((b!
=1)&&(b!
=2)){
printf("输入错误,接下来1:
对该设备信息修改完成2:
还需要对该设备进行修改\n");
scanf("%d",&b);
}
}while(b==2);
fp=fopen(,"w");
fseek(fp,0,0);fprintf(fp,"\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\r\n",eup[0].id,eup[0].kind,eup[0].name,eup[0].price,eup[0].in_date,eup[0].reject,eup[0].out_date);
for(n=1;nfprintf(fp,"\r\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\r\n",eup[n].id,eup[n].kind,eup[n].name,eup[n].price,eup[n].in_date,eup[n].reject,eup[n].out_date);
fclose(fp);
该函数曾出现过的问题:
对文件修改必须以正行修改,经老师要求后改成了可以对行内的某一条目修改,修改起来更加方便。
(7)删除delect()
读取文件内容,但读写时跳过需要删除的行不读,然后把读取出的内容重新写入文件
voiddelect(){
inti,j,n,k=0;
charmystring2[100][100],stri[100];
FILE*fp;
show();
printf("想要删除那条?
0~?
\n");
scanf("%d",&i);
j=load();
while(i>j-1)
{
printf("输入的行数大于实际行数,重新输入");
scanf("%d",&i);
}
fp=fopen(,"r");
fseek(fp,0,0);//以行为单位一行行的读取,但最多肚100个字节
for(n=0;nif(n!
=i){
if(k==0)
fgets(mystring2[n],100,fp);
else
fgets(mystring2[n-1],100,fp);
}
else{
fgets(stri,100,fp);
k=1;
}
}
fclose(fp);
fp=fopen(,"w");
fseek(fp,0,0);
for(n=0;nfprintf(fp,"%s",mystring2[n]);
fclose(fp);
}
(8)显示数据函数show()
charmystring2[100],*t={"\;"};i=load();//读取文件数量
if(i==-1||i==0)//如果文件打开失败或文件内没有内容
{printf("can'topennodata");
return;}
for(n=0;n
fgets(mystring2,100,fp);//按行的方式一行行显示文件
}
7.2调试与测试
课程设计中出现的问题:
在上面的每一部分程序段中有说明。
调试:
(1)显示show()
图10显示内容界面图
(2)修改modify()
界面
图11修改界面图
修改后显示
图12修改结果
(3)删除delect()
图13删除界面
删除后
图14修改界面
(4)添加addItem()
图15添加界面
图16添加前
图17添加后
(4)查找check()
图18界面
图19查找结果
(5)分类sort()
图20分类界面
说明:
看倒数第二列数据,部分大小写
图21分类结果
八:
总结
(1)在出现问题时可以利用多种渠道获得帮助,可以向老师咨询和借助网络。
(2)出现问题时需要去分析问题的现象,从现象去考虑可能引起问题的地方。
(3)进行调试或编程时采取一步步循序渐进的办法先完成一个子功能,在把一个个功能整合起来。
总结:
通过这次的课程设计,大大的丰富了我的C语言知识,并对这门课程有了进一步的了解,在我们这个专业里也占有很重要的地位。
我知道仅仅学习课本知识是远远不够的,还需要通过实践来检验和提高。
通过这次的任务,我进一步的掌握了C语言的一些基本知识,但同时也知道这还是远远不够的,还需要通过更多的实践来掌握更多的知识。
同时,这个课程也培养了我的编程习惯,让我能更好的编写和解决问题。
九:
成员设计内容
成员:
1
陈太斌:
所有
十:
参考资料
[1]谭浩强.C程序设计(第三版)[M].北京:
清华大学出版社
[2]谭浩强.C程序设计题解与上机指导(第三版)[M].北京:
清华大学出版社,2005.
[3]郭翠英.C语言课程设计案例精编:
中国水利水电出版社,2004
[4]Cqzl24ENW7V5bPui_ABtlgUfX4y9OCXvopmw1vDS74hoKd41fLJV3S_Te
2012.07.24
[5]
2008.10.08
[6]
2011.11.23