软件课设.docx
《软件课设.docx》由会员分享,可在线阅读,更多相关《软件课设.docx(10页珍藏版)》请在冰豆网上搜索。
软件课设
课程设计说明书
课程名称程序分析
专业
班级
学号
学生姓名
指导教师
2012年6月
摘要
本课题的主要任务是开发一款代码行数统计器,专门用于统计C语言或C++语言程序代码文件。
该统计器的主要功能是统计代码文件的文件行数、有效代码行数、注释行数、空白行数,以及计算代码的注释率。
和那些只能统计单个文件的统计器不同,这款统计器能够接受文件夹路径,批量统计整个文件夹的所有文件,包括子文件夹中的有效文件。
这样可以大大的提高统计效率,节约用户的时间,使编程人员能集中更多精力编写程序。
该统计器在测试时统计了大量的文件,基本上没有错误,精度相当高,用户可安全使用。
本课题所用的编译环境是C-free5,最终结果exe可执行文件。
关键词
程序分析代码注释行数
目录
一目的..............................................................................2
二需求分析2
三概要设计2
四详细设计3
五调试分析8
六测试结果9
七用户使用说明10
八课程设计总结10
程序分析
一目的
读入一个C程序,统计程序中代码、注释和空行的行数以及函数的个数和平行行数并利用统计信息分析评价该程序的风格。
二需求分析
1、文本串非空且以C程序文件形式存放,文件由用户建好并设立路径。
2、把C程序文件按字符顺序读入源程序;
3、边读入程序,边识别统计代码行、注释行和空行,同时还要识别函数的开始和结束,以便统计其个数和平均行数。
4、在计算机终端输出的结果是:
函数的个数,函数的总行数,函数的平均行数,总函数,空行的行数,注释的行数,函数的平均长度的等级,注释等级,空行等级。
5、测试数据:
C文本文件为本次练习中的hello.c.
三概要设计
1、程序采用对文件逐个顺寻读入字符,存放在数组的方法,边读入便统计。
以下便是统
计的具体过程。
A:
打开文件,读取文件,于数组中存放。
B:
调用去掉左右空格的函数,为了节省栈的空间。
C:
计算注释行数,包含三种下情况的注释行计算。
D:
行为空,则记录空行行数。
E:
计算函数个数,函数总行数,平均行数。
主要
是运用右小括号和左大括号匹配。
F:
计算函数平均行数等级,注释行数等级,空行行数等级。
2、本程序包含2个模块
A、主程序模块,其中主函数为
voidmain()
{定义变量;
统计文件中的注释行数,空格的行数,函数个数,函数的个数,函数总行数,函
数的平均行数;
判断函数的平均长度的等级,注释等级,空行等级;
输出测试结果;
}
B、去掉左空格函数;voidStrLTrim(char*pszStr)
去掉右空格函数;voidStrRTrim(char*pszStr)
四详细设计
1、各类行数计算的过程全部包含的在主函数mian()中。
A:
打开文件,读取文件,于数组中存放。
printf("请输入你要验证的文件:
");
scanf("%s",&filepath);
FILE*fp=NULL;
fp=fopen(filepath,"r");//打开文件
if(!
fp){
printf("can'tfindthefile.\n",filepath);
return-1;
}
for(line=0;fgets(buf,sizeofbuf,fp)!
=NULL;line++)//读取文件的每一行放到数组file内,一行最大的字节数为1024
{
file[line]=(char*)malloc(strlen(buf)+1);
strcpy(file[line],buf);
}
B:
调用去掉左右空格的函数,为了节省栈的空间。
for(i=0;iStrLTrim(file[i]);//去掉左空格
StrRTrim(file[i]);//去掉右空格
linelength=strlen(file[i]);
/*if(linelength==0){
continue;
}
*/
C:
计算注释行数,包含三种下情况的注释行计算。
if((file[i][0]=='/')&&(file[i][1]=='/'))//如果出现'//'证明出现了一行注释
{
cometline++;
}
if((file[i][0]=='/')&&(file[i][1]=='*'))//
{
if((file[i][linelength-2]=='*')&&(file[i][linelength-1]=='/'))//如果在同一行的结束就有注释的结束标志"*/"
{
cometline++;
cometBegin=0;
free(file[i]);
continue;
}
else{
if(cometBegin==0){
cometBegin=1;//注释的结束标志不在同一行,设置变量cometBegin
cometline++;
free(file[i]);
continue;
}
}
}
if((file[i][linelength-2]=='*')&&(file[i][linelength-1]=='/')){
if(cometBegin==1)//遇到注释结束标志并且前面已经有了注释的开始标志“/*”
{
cometline++;
cometBegin=0;
}
}
if(cometBegin==1)//注释的开始算一行
{
cometline++;
free(file[i]);
continue;
}
if(strcmp(file[i],"")==0&&cometBegin==0)//如果这一行为空,而且不是在注释范围内
{
blankline++;
}
D:
行为空,则记录空行行数。
if(strcmp(file[i],"")==0&&cometBegin==0)//如果这一行为空,而且不是在注释范围内
{
blankline++;
}
E:
计算函数个数,函数总行数,平均行数。
主要是运用右小括号和左大括号匹配。
for(j=0;j{
if(file[i][j]==')')//遇到右小括号进行标识tag1
{
tag1++;
}
if(file[i][j]=='{'&&tag1!
=0)//如果在有小括号的前提下遇到左大括号
{
tag2++;//大括号标识加1
flag=1;//证明已经遇到过"){"
if(tag1==1)//第一次遇到"){"代表着函数的开始
{
function_start[func_number]=i;//记录函数的开始行数
}
}
if(file[i][j]=='}'&&flag==1)
{
tag2--;//遇到结束,-1
}
if(tag2==0&&flag!
=0)//如果已经出现过"){",而且已经匹配完“{”和“}”了
{
function_end[func_number++]=i;//记录函数结束的行数
flag=0;
tag1=0;
}
}
free(file[i]);
}
flag=0;//借用变量flag
for(i=0;i{
flag+=function_end[i]-function_start[i];//计算函数总行数
}
flag=flag/func_number;//计算函数平均行数
F:
计算函数平均行数等级,注释行数等级,空行行数等级中的范例以及输出。
printf("Thenumberoffunctionsare:
%i\n",func_number);
printf("Theaverageoffunctionlineis:
%i\n",flag);
if(flag>=10&&flag<=15){
printf("Theleveloffunctionis:
A\n");
}
if(flag>=8&&flag<=9||flag>=16&&flag<=20)
{
printf("Theleveloffunctionis:
B\n");
}
if(flag>=5&&flag<=7||flag>=21&&flag<=24)
{
printf("Theleveloffunctionis:
C\n");
}
if(flag<5||flag>24)
{
printf("Theleveloffunctionis:
D\n");
}
flag=100*cometline/line;//计算注释行数占总代码行数的百分比
printf("Thetotalnotelinesare:
%i\n",cometline);
if(flag>=15&&flag<=25)
{
printf("Thelevelofnoteis:
A\n");
}
if(flag>=10&&flag<=14||flag>=26&&flag<=30)
{
printf("Thelevelofnoteis:
B\n");
}
if(flag>=5&&flag<=9||flag>=31&&flag<=35)
{
printf("Thelevelofnoteis:
C\n");
}
if(flag<5||flag>35)
{
printf("Thelevelofnoteis:
D\n");
}
五调试分析
1、当输入较大的文件程序进行分析的时候,会出现错误和报警,但是对于较小的文件程序却完全正确。
经过分析,发现是程序中的空格太多,导致读取文件的时候,定义的数组不足存储文件字符,还有计算函数个数和行数的时候,进行括号匹配过程中,栈的空间不足,所以最后增加了两个函数,去掉左空格函数voidStrLTrim(char*pszStr),去掉右空格函数;voidStrRTrim(char*pszStr)。
这两个函数使自己验证的程序,不管大还是小的,程序的分析输出都是正确的。
2在本程序的开始定义了一个constchar*pWord[]={"int","long","double","char","int*","long*","double*","char*","void","void*"};这个程序段是在网上收集资料的时候就定义的,自己感觉这个是定义关键字,方便查找函数还有计算函数个数,可是主函数中查找函数是用右小括号以及左大括号,设置变量标记以及计算的,就把这个定义去掉,但是发现删除后出现错误和报警,之后猜想这个定义可能是起到辅助查找函数的作用。
3在计算函数注释行的时候,开始的时候只考虑了具有”//”这种情况,但是发现其他的程序中,不仅包含了/*这种类型,还有一种就是注释行不在一行的情况,针对这些情况,自己改进了程序if(cometBegin==0){
cometBegin=1;//注释的结束标志不在同一行,设置变量cometBegin
cometline++;
if((file[i][linelength-2]=='*')&&(file[i][linelength-1]=='/'))//如果在同一行的结束就有注释的结束标志"*/"
{
cometline++;
cometBegin=0;
六测试结果
七用户使用说明
1、用户自己建立一个C文本文件并设立好路径,相应的程序中的路径也要与其匹配。
2、直接进行编译,链接就可以了。
3、按照运行界面的提示,输入运行程序名或者其他程序名,就可以得到要求的数据以及等级。
八课程设计总结
回顾起此次课程设计,我们仍感慨颇多,的确,自从拿到题目到完成整个编程,从理论到实践,在整整一周的时间里,学到很多很多的东西,同时不仅巩固了以前所学过的知识,而且学到了很多在以前所没有学到东西。
通过这次课程设计使我们懂得了理论知识与实际操作相结合的重要,如果没有上机调试有些问题可能就发现不了,通过调试去发现问题、解决问题,从而提高自己独立思考的能力。
在整个设计过程中遇到了很多问题,发现了自己的不足之处,对一些前面学过的知识理解得不够深刻,掌握得不够牢固,通过这次课程设计之后,我们把前面所学过的知识又重新复习了一遍。
在设计中虽说遇到了很多困难,有时苦思冥想不得其解,但是通过和同组同学讨论,我们逐一突破,正所谓三人行,必有我师,对团队协作有了更深刻的认识。
此外,在如何快捷的查找资料和应用办公软件方面也是一次锻炼。
这次课程设计从拿到题目到分析题目、编写程序、运行结果直至排版打印,在整个过程中对我们计算机知识的应用和操作是一次全面的提高。
同时,老师在整个过程中始终在我们中间答疑解惑、耐心指导,这种认真工作的态度,勤勤恳恳的敬业精神,将对以后学习、生活有很多启示和帮助。
生活就是这样,汗水预示着结果也见证着收获。
劳动是人类生存生活永恒不变的话题。
通过实际动手做,我想说,编程确实有些辛苦,但苦中也有乐,在这个团队的任务中,一起的努力可以让我们有说有笑,相互帮助,配合默契。
对我们而言,知识上的收获可喜的,精神上的丰收是重要的。
挫折是一份财富,经历是一份拥有。
这次课程设计必将是大学生活中一个非常美好的回忆!
参考文献
《数据结构(c语言版)例题详解与课程设计指导》第二版袁志祥、秦锋主编中国科学技术大学出版社出版