當前位置:編程學習大全網 - 源碼下載 - 問題描述]讀入壹個C程序,統計程序中代碼、註釋

問題描述]讀入壹個C程序,統計程序中代碼、註釋

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define TRUE 1

#define FALSE 0

#define BOOL int

#define MAXSIZE 5000

#define COUNT 20 // 可以統計的最大的文件個數

#define LEN 20 // 文件名的最大長度

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

voidcheckfile(char *filename,int i);

voidanaly(char filename[COUNT][LEN],int n);

BOOLGetIn(int *n);

//函數屬性結構

typedefstruct {

char filename[20]; //每壹個函數的名字

int length; //每壹個函數的長度

int pos; //每壹個函數的位置

}Fun;

//統計結構的聲明

typedefstruct {

int comments; //純註釋的個數

int comment; //混合註釋個數

int blank; //空行的個數

Fun fun[MAXSIZE]; //函數的屬性

int others; //除去函數中代碼外其余的代碼個數

int funcount; //函數的個數

}Analy;

//串的基本操作ADT

//檢測是否為空串

BOOLStrEmpty(char *s)

{

if(s[0]=='\0')

return TRUE;

return FALSE;

}

//查看S1中是否有值為S2的子串,若有則返回第壹個子串的位置,若無則返回-1;

intFind(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;

}

//讀取文件中的壹行字符

voidHaveLine(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;

}

//判斷壹行字符是不是註釋

intIsCom(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;

}

//判斷壹行字符是不是空白

BOOLIsBlank(char *s)

{

s= IgnoreB(s);

if(*s== '\0')

return TRUE;

return FALSE;

}

intIsFunB(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;

}

voidprintR(int aver ,int comc,int blanks )

{

//按代碼級別判定標準輸出分析結果

int i;

char Grade[4][15] = {"A:Excellent","B: Good","C: just So-So","D: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 spacestyle\n",Grade[i]);

}

//打印輸出結果

voidprint(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(" 程序源代碼分析結果如下所示\n\n");

printf(" 代碼行數: %d\n",sum -An->blank - An->comment - An->comments);

printf(" 註釋行數: %d\n",An->comments +An->comment);

printf(" 空行數: %d\n",An->blank);

printf(" 代碼 註釋 空行\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);

printf("\n");

//按代碼級別判定標準輸出分析結果

printR(aver,comc,blanks);

}

voidcheckfile(char *filename,int i)

{

FILE *fp;

while((fp = fopen(filename,"r"))== NULL)

{

printf("對不起!文件不存在%s\n",filename);

printf("\n請重新輸入第%d個源文件: ",i+1);

scanf("%s",filename);

}

}

BOOLGetIn(int *n)//規範輸入的數據,只能為數字

{

char c;

*n = 0;

fflush(stdin);

c = getchar();//當輸入壹串數據並按回車後,getchar()取出緩存隊列中的第壹個字符

while(c != '\n'){

if(c == '0' && n == 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;

}

voidanaly(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");

for (i = 0 ;i < n; i++)//遍歷所有的文件

{

if((fp =fopen(filename[i],"r")) == NULL)

{

printf("cannot open the file%s\n",filename[i]); //輸出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); //打印分析結果

}

voidmain()

{

int n,i;

char c;

char filename[COUNT][LEN];

printf("\t-------------------------------------------------------------\n");

printf("\t 程序源代碼分析軟件 BY 沈航電子信息工程學院--王盼 \n");

printf("\t--------------------------------------------------------------\n");

while(1){

n=0;

printf("\t\t\t**********程序分析*********\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;

}

}

  • 上一篇:人臉識別壹體機的原理是什麽?
  • 下一篇:判斷戶型好壞的五個硬指標 方正最好
  • copyright 2024編程學習大全網