需求分析1) 问题描述读入一个C程序,统计程序中代码、注释和空行数以及函数的个数和平均行数,并利用统计信息分析评价该程序风格2) 基本要求如下:(1)、把C程序文件按字符顺序读入源程序;(2)、边读入程序,边识别统计代码行、注释行和空行,同时还要识别函数的开始和结束,以便统计其个数及平均行数3)、程序风格分为代码注释和空行三方面每方面分A、B、C、D四个等级 A B C D代码(函数的平均长度) 10~15行 8~9或16~20 5~7或21~24 <5或>24 注释(占总行数比例) 15~25% 10~14或26~30% 5~9或31~35% <5%或>35% 空行(占总行数比率) 15~25% 10~14或26~30% 5~9或31~35% <5%或>35%3)输入输出例以下是对程序文件ProgAnal.C分析的输出结果示例: The results of analysing program file "ProgAnal.C": Lines of code :180 Lines of comments: 63 Blank lines: 52 Code Comments Space 61% 21% 18% The program includes 9 functions. The average length of a section of code is 12.9 lines. Grade A: Excellent routine size style. Grade A: Excellent commenting style. Grade A: Excellent white space style.1. 概要设计1).头文件引用与宏定义:#include #include #include #define TRUE 1#define FALSE 0#define BOOL int#define MAXSIZE 5000#define COUNT 20 // 可以统计的最大的文件个数#define LEN 20 // 文件名的最大长度2).所用存储结构//函数属性结构typedef struct { char filename[20]; //每一个函数的名字 int length; //每一个函数的长度 int pos; //每一个函数的位置}Fun;//统计结构的声明typedef struct { int comments; //纯注释的个数 int comment; //混合注释个数 int blank; //空行的个数 Fun fun[MAXSIZE]; //函数的属性 int others; //除去函数中代码外其余的代码个数 int funcount; //函数的个数}Analy;2. 详细设计1).函数功能及声明BOOL StrEmpty(char *s)//S是不是空int Find(char *s1,char *s2)//查找S1中是否有值为S2的子串void HaveLine(FILE *fp,char *s)//重文件中获取一行char* IgnoreB(char *s)//截断一行的空字符int IsCom(char *s)//判断一行是不是注释BOOL IsBlank(char *s)//判断一行是不是空格BOOL IsFunB(char *s)//判断一行是否是函数的开头void PrintMax(Analy *An)//打印最大函数的信息void printR(int aver ,int comc,int blanks )//打印代码风格级别void print(Analy *An)//void checkfile(char *filename,int i)//检测文件是否存在BOOL GetIn(int *n)//规输入的数据,只能为数字void analy(char filename[COUNT][LEN],int n)//分析单个文件void savelog()//保存日志2)详细源代码//检测是否为空串BOOL StrEmpty(char *s){ if(s[0]==\0) return TRUE; return FALSE; }//查看S1中是否有值为S2的子串,若有则返回第一个子串的位置,若无则返回-1;int Find(char *s1,char *s2){ int i = 0,j = 0; if(strlen(s1) < strlen(s2)) return -1; while (s1[i]!=\0) { if(s1[i] == s2[j]) { i++; j++; if(s2[j]==\0) return i-j; continue; } i++; j=0; } return -1; }//读取文件中的一行字符void HaveLine(FILE *fp,char *s){ while(!feof(fp)) { *s = fgetc(fp); if(*s==\n){ //若果是一行的结尾则表示取完了一行 *s=\0; return; } s++; } *s = \0;}//忽略一行字符开头的空格和tab,返回截断后上的串指针char* IgnoreB(char *s){ while (*s== || *s== ) s++; return s;}//判断一行字符是不是注释int IsCom(char *s){ int posc,pos1,pos2; s= IgnoreB(s); posc = Find(s,"//"); if(posc == 0)//此行仅有注释,无代码; return 1; if(posc == -1) return 0; pos1 = Find(s,"\""); pos2 = Find(&s[pos1+1],"\""); if(posc > pos1 && posc < pos2) return 0; return 2; }//判断一行字符是不是空白BOOL IsBlank(char *s){ s= IgnoreB(s); if(*s== \0) return TRUE; return FALSE;}BOOL IsFunB(char *s){ int i,j,pos,pos2; //有分号,if while for的不是函数开头 if(Find(s,";") != -1 || Find(s,"if") != -1 || Find(s,"for") != -1 || Find(s,"while") != -1||Find(s,"switch") != -1) return FALSE; //没有小括号的不是函数开头 if((pos = Find(s,"(")) == -1) return FALSE; s = IgnoreB(s); i = Find(s," "); j = Find(s," "); if (i != -1 && j != -1) i = i > j ? j : i; else if (i == -1) i = j; else if (1 == -1 && j == -1) return FALSE; if (i > pos) return FALSE; s = &s[i]; s = IgnoreB(s); pos2 = Find(s,"("); if(*s == \0 || *s == ( ||pos2 > pos) return FALSE; return TRUE; }//打印最大的函数属性void PrintMax(Analy *An){ // FILE *fp; int i,j = 0; // int len; for(i = 1;i < An->funcount ;i++) if(An->fun[j].length < An->fun[i].length)//找出最大的函数的位置 j = i; if(An->fun[j].length < 0 || An->fun[j].pos < 0){ printf(" there are not any function in the files");//打印出函数所在的文件和位置 return; } printf(" The length of lengthest function have %d lines \n",An->fun[j].length);//打印长度 printf(" The pos of lengthest function is in %s the %dth line\n",An->fun[j].filename,An->fun[j].pos);//打印出函数所在的文件和位置 printf(" The length of lengthest function have %d lines \n",An->fun[j].length);//打印长度}void printR(int aver ,int comc,int blanks ){ //按代码级别判定标准输出分析结果 int i; char Grade[4][15] = {"Excellent","Good","So-So","Bad"};//定义四个级别段 //判定代码的级别 if (aver <= 15 && aver >=10) i = 0; else if((aver <=20 && aver >= 16) || aver <= 9 && aver >= 8) i = 1; else if((aver <=7 && aver >= 5) || aver <= 24 && aver >=21) i = 2; else if ((aver <5) || (aver > 24)) i = 3; printf(" Grade %s routin。