5

新手,这代码调试了一晚上弄不好,求高手帮忙看看

感激不尽

#include
#include
#include
#define TRUE 1
#define FALSE 0
#define BOOL int
#define MAXSIZE 5000
#define COUNT 20 // 可以统计的最大的文件个数
#define LEN 20 // 文件名的最大长度

//检测是否为空串
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 routine code style\n",Grade[i]);


//判定注释的级别
if (comc<= 25 && comc >= 15)
    i = 0;
else if((comc <=14 && comc >= 10) || comc <= 30 && comc >=26)
    i = 1;
else if((comc <=9 && comc >= 5) || comc <= 35 && comc >=31) 
    i = 2;
else if((comc <5) ||  (comc > 35))
    i = 3;
printf("        Grade %s routine commenting style\n",Grade[i]);

//判定空行的级别
if (blanks <= 25 && blanks >= 15)
    i = 0;
else if((blanks <=14 && blanks >= 10) || blanks <= 30 && blanks >=26)
    i = 1;
else if((blanks <=9 && blanks >= 5) || blanks <= 35 && blanks >=31) 
    i = 2;
else if((blanks <5) ||  (blanks > 35))
    i = 3;
printf("        Grade %s  white space style\n",Grade[i]);

}

//打印输出结果
void print(Analy *An)
{

int sum = 0,funcode = 0;
int i,  comc , blanks, aver ,code;
for(i = 0;i < An->funcount ;i++)//求函数的代码总数
    funcode += An->fun[i].length;

//求所有的代码总数
sum += An->blank;
sum += An->comments;
sum += An->comment;
sum += An->others;
sum += funcode;

if(sum == 0)//防止除数sum为0
    sum = 1;
if(An->funcount == 0)//防止除数m为0
    aver = 0;
else
    aver = funcode/An->funcount;

comc = (An->comments + An->comment)*100/sum;
blanks = ((An->blank)*100)/sum;
code =  100 - comc - blanks; //((funcode + An->others)*100)/sum;

printf("    The results of analysing program file:\n\n");
printf("        Lines of code:      %d\n",sum - An->blank - An->comment - An->comments);
printf("        Lines of comments:  %d\n",An->comments + An->comment);
printf("        Blank lines:        %d\n",An->blank);
printf("        Code    Comments    Space\n");
printf("        _____   ________    _____\n");
printf("        -----   --------    -----\n");
printf("        %d%%   %d%%     %d%%\n",code,comc,blanks);
printf("        The program includes %d functions\n",An->funcount);
printf("        The average length of section of function is %d\n",aver);
PrintMax(An);
printf("\n");
//按代码级别判定标准输出分析结果
printR(aver,comc,blanks);

}

void checkfile(char *filename,int i)
{
FILE *fp;
while((fp = fopen(filename,"r")) == NULL)
{
printf("文件不存在 %s\n",filename);
printf("\n请重新输入第%d个源文件: ",i+1);
scanf("%s",filename);
}

}

BOOL GetIn(int *n)//规范输入的数据,只能为数字
{
char c;
*n = 0;
fflush(stdin);
c = getchar();//当输入一串数据并按回车后,getchar()取出缓存队列中的第一个字符
while(c != '\n'){
if(c == '0')
printf("输入有误!请重新输入....\n");
if(c >= '0' && c <= '9')
*n = (*n) * 10 +c - 48;
else{
printf("输入有误!请重新输入....\n");
fflush(stdin);//清空(刷新)缓存里的内容,以防被下次getchar()取用
return FALSE;
}
c = getchar();

}
return TRUE;

}

void analy(char filename[COUNT][LEN],int n)
{
FILE *fp;//分析源文件指针
FILE *fpp;//日志文件指针
Analy An;//程序统计结构体
char s[200];//存储每行的文件
BOOL begin = 0,start = 0;//设置函数开始标记
int i,j = -1,pos = 0;//函数的位置 长度信息
//c检测函数内大括号的匹配,comtype是注释的类型
int c=0,comtype;
An.blank = 0;

An.comments = 0;
An.comment = 0;
An.others = 0;
An.funcount = 0;
if((fpp = fopen("log.txt","w")) == NULL)//建立日志文件
printf("cannot open the file %s\n",filename[i]);

for (i = 0 ;i < n; i++)//遍历所有的文件
{
    if((fp = fopen(filename[i],"r")) == NULL)
    {
        printf("cannot open the file %s\n",filename[i]);
        getchar();
        exit(0);
    }

    pos = 0; //函数在新一个文件中的位置初始化
    while (!feof(fp))
    {
        HaveLine(fp,s); //从文件中读取一行数据
        pos++;  //每个函数在文件中开始的位置
        //分类统计文件中的代码个数
        comtype = IsCom(s);
        if (comtype ==1)
        {
            An.comment++;
            continue;
        }
        if (comtype == 2)
            An.comments++;
        if (IsFunB(s))
        {
            fprintf(fpp,"%s \n",s);//提取每个函数的名字写入到文件

            j++; //j为函数的个数-1;
            c = 0;//大括号个数初始化为0
            begin = TRUE;
            strcpy(An.fun[j].filename,filename[i]); //记录函数在哪个文件中
            An.fun[j].pos = pos;
            An.fun[j].length = 1;

        }
        else if(IsBlank(s))
               An.blank++;  
        else if(begin){
                An.fun[j].length++;
                if (Find(s,"{") != -1) //检测是否进入到了函数体内
                {
                    c++;
                    start = TRUE;
                }
                if (Find(s,"}") != -1) //检测是否一个函数的结束
                    c--;
                if (c==0 && start)
                {
                    begin = FALSE;
                    start = FALSE;
                }
        }
        else
               An.others++;     
    }
fclose(fp);//关闭分析文件

}
fclose(fpp);//关闭日志文件

An.funcount = j+1; //把函数的个数保存
print(&An); //打印分析结果

}

void main()
{
int n,i;
char c;
char filename[COUNT][LEN];
printf("\t-------------------------------------------------------------\n");
printf("\t 计算机学院网络工程三班*--------*张菲*--*学号3107007062\n");
printf("\t--------------------------------------------------------------\n");

while(1){
n=0;
printf("\t\t\tIII-----程序分析----III       \n");
printf("请输入要分析的源文件的个数: ");
while(!GetIn(&n) || n <= 0){

    printf("请输入要分析的源文件的个数: ");
}

for(i = 0 ;i < n ;i++)
{
    printf("\n请输入第%d个源文件: ",i+1);
    scanf("%s",filename[i]);
    checkfile(filename[i],i);
    fflush(stdin);
}
analy(filename,n);

printf("\t*************************是否继续使用? Y/N***************************\n");
c = getchar();
if(c == 'Y' || c == 'y')
continue;
break;

}

}

查看全部
u011556582
蜗牛998
2016/06/15 13:51
  • 点赞
  • 收藏
  • 回答
    私信

1个回复