# include & ltstdlib.h & gt
# include & ltstring.h & gt
#定義真1
#定義假0
#定義布爾整型
#定義MAXSIZE 5000
#define COUNT 20 //可以計數的最大文件數。
#定義LEN 20 //文件名的最大長度
# include & ltstdio.h & gt
# include & ltstdlib.h & gt
# include & ltconio.h & gt
voidcheckfile(char *filename,int I);
void analy(char filename[COUNT][LEN],int n);
BOOLGetIn(int * n);
//函數屬性結構
typedefstruct {
字符文件名[20];//每個函數的名稱
int長度;//每個函數的長度
int pos//每個函數的位置
}好玩;
//統計結構的陳述
typedefstruct {
int註釋;//純註釋的數量
int註釋;//混合註釋的數量
int blank//空白行數
fun fun[MAXSIZE];//函數的屬性
int others//函數中代碼以外的代碼數。
int funcount//函數的數量
} Analy
//字符串的基本操作ADT
//檢測是否為空字符串。
BOOLStrEmpty(字符)
{
if(s[0]=='\0 ')
返回TRUE
返回FALSE
}
//檢查S1中是否有值為S2的子串,如果有,返回第壹個子串的位置,如果沒有,返回-1;
intFind(char *s1,char *s2)
{
int i = 0,j = 0;
if(strlen(s 1)& lt;strlen(s2))
return-1;
while (s1[i]!='\0')
{
if(s1[i] == s2[j])
{
i++;
j++;
if(s2[j]=='\0 ')
返回I-j;
繼續;
}
i++;
j = 0;
}
return-1;
}
//讀取文件中的壹行字符。
voidHaveLine(FILE *fp,char *s)
{
而(!feof(fp))
{
* s = fgetc(FP);
如果(*s=='\n'){ //在壹行的末尾,則表示該行已被占用。
* s = ' \ 0
返回;
}
s++;
}
* s = ' \ 0
}
//忽略壹行字符開頭的空格和制表符,返回截斷的字符串指針。
char*IgnoreB(char *s)
{
while (*s== ' ' || *s== ' ')
s++;
返回s;
}
//判斷壹行字符是否是註釋。
intIsCom(char *s)
{
int posc,pos1,pos2
s = IgnoreB(s);
posc = Find(s,“//”);
If(posc == 0)//這行只有註釋,沒有代碼;
返回1;
if(posc == -1)
返回0;
pos1 = Find(s," \ ");
pos2 =查找(& amps[pos1+1]," \ " ";
if(posc & gt;pos 1 & amp;& ampposc & ltpos2)
返回0;
return 2;
}
//判斷壹行字符是否為空。
布爾值空白(字符)
{
s = IgnoreB(s);
if(*s== '\0 ')
返回TRUE
返回FALSE
}
intIsFunB(char *s)
{
int i,j,pos,pos 2;
//有分號,if while for不是函數的開頭。
如果(找到(s),;)) != -1 ||Find(s," if ")!= -1 || Find(s," for ")!= -1 ||Find(s," while ")!= -1||Find(s," switch ")!= -1)
返回FALSE
//沒有括號的不是函數的開頭。
if((pos = Find(s,"(")== -1)
返回FALSE
s = IgnoreB(s);
i = Find(s," ");
j = Find(s," ");
如果(我!=-1 & amp;& ampj!= -1)
i = i & gtj?j:我;
else if (i == -1)
I = j;
else if(1 = =-1 & amp;& ampj == -1)
返回FALSE
如果(i & gt位置)
返回FALSE
s = & amps[I];
s = IgnoreB(s);
pos2 = Find(s,"(");
if(* s = = ' \ 0 ' | | * s = = '(' | | pos 2 & gt;位置)
返回FALSE
返回TRUE
}
voidprintR(int aver,int comc,int blanks)
{
//根據代碼級別判斷標準輸出分析結果。
int I;
char Grade[4][15] = {"A:優秀"," B:良好"," C:壹般"," D:差" };//定義四個級別段。
//確定代碼的級別
if(aver & lt;= 15。& ampaver & gt=10)
I = 0;
else if((aver & lt;= 20 & amp& ampaver & gt= 16)| | aver & lt;= 9 & amp& ampaver & gt= 8)
I = 1;
else if((aver & lt;= 7 & amp& ampaver & gt= 5)| | aver & lt;= 24 & amp& ampaver & gt=21)
I = 2;
else if((aver & lt;5)| |(aver & gt;24))
I = 3;
printf("等級%s例程代碼樣式\n ",等級[I]);
//確定註釋的級別
if(comc & lt;= 25 & amp& ampcomc & gt= 15)
I = 0;
else if((comc & lt;=14。& ampcomc & gt= 10)| | comc & lt;= 30 & amp& ampcomc & gt=26)
I = 1;
else if((comc & lt;= 9 & amp& ampcomc & gt= 5)| | comc & lt;= 35 & amp& ampcomc & gt=31)
I = 2;
else if((comc & lt;5)| |(comc & gt;35))
I = 3;
printf(" Grade %s例程註釋樣式\n ",Grade[I]);
//確定空白行的級別
if(空格& lt= 25 & amp& ampblanks & gt=15)
I = 0;
else if((blanks & lt;=14。& ampblanks & gt= 10) ||空白& lt= 30 & amp& ampblanks & gt=26)
I = 1;
else if((blanks & lt;= 9 & amp& ampblanks & gt= 5) ||空白& lt= 35 & amp& ampblanks & gt=31)
I = 2;
else if((blanks & lt;5)| |(blanks & gt;35))
I = 3;
printf(" Grade % s white space style \ n ",Grade[I]);
}
//打印輸出結果
無效打印(分析)
{
int sum = 0,funcode = 0;
int i,comc,blanks,aver,code
for(I = 0;我& lt安-& gt;funcountI++)//求函數的代碼總數。
funcode+= An-& gt;好玩[我]。長度;
//找出所有代碼的總數
sum+= An-& gt;空白;
sum+= An-& gt;評論;
sum+= An-& gt;評論;
sum+= An-& gt;其他;
sum+= funcode;
If(sum == 0)//防止除數和為0。
sum = 1;
if(An-& gt;Funcount == 0)//防止除數m為0。
aver = 0;
其他
aver = funcode/An-& gt;funcount
comc =(An-& gt;註釋+An-& gt;評論)* 100/sum;
blanks =((An-& gt;空白)* 100)/sum;
code = 100-comc-blanks;//((funcode+An-& gt;其他)* 100)/sum;
Printf("程序源代碼分析結果如下\ n \ n ");
Printf("代碼行:%d\n ",sum-An-& gt;blank-An-& gt;註釋-An-& gt;評論);
Printf("註釋行號:%d\n ",An-& gt;註釋+An-& gt;評論);
Printf("空白行數:%d\n ",An-& gt;空白);
Printf("代碼註釋空行\ n ");
printf(" * * * * * * * * * * * * * * * * * \ n ");
printf(" * * * * * * * * * * * * * * * * * \ n ");
printf(" %d%% %d%% %d%%\n ",code,comc,blanks);
printf("該程序包括%d個函數\n ",An-& gt;funcount);
printf("函數段的平均長度為%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 ",文件名);
printf(" \ n請重新輸入%d源文件:",I+1);
scanf("%s ",文件名);
}
}
BOOLGetIn(int *n)//規範中輸入的數據只能是數字。
{
char c;
* n = 0;
fflush(stdin);
c = getchar();//當妳輸入壹串數據並按enter鍵時,getchar()取出緩存隊列中的第壹個字符。
而(c!= '\n'){
if(c = = ' 0 ' & amp;& ampn == 0)
Printf("輸入錯誤!請重新輸入...\ n ");
if(c & gt;= ' 0 ' & amp& ampc & lt= '9')
* n =(* n)* 10+c-48;
否則{
Printf("輸入錯誤!請重新輸入...\ n ");
fflush(stdin);//清空(刷新)緩存的內容,防止下次被getchar()訪問。
返回FALSE
}
c = getchar();
}
返回TRUE
}
void analy(char filename[計數][長度],int n)
{
FILE * fp//分析源文件指針
FILE * fpp//日誌文件指針
分析;//程序統計結構
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("無法打開文件% s \ n ");
for(I = 0;我& ltn;I++)//遍歷所有文件。
{
if((fp =fopen(filename[i]," r))= = NULL)
{
printf("無法打開文件%s\n ",文件名[I]);//輸出文件名[i]
getchar();
退出(0);
}
pos = 0;//初始化函數在新文件中的位置。
而(!feof(fp))
{
哈夫林(fp,s);//從文件中讀取壹行數據
pos++;//文件中每個函數開始的位置。
//分類統計文件中的編碼數
comtype = IsCom(s);
if (comtype ==1)
{
an . comment++;
繼續;
}
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[I]);//函數記錄在哪個文件中?
樂趣;樂趣。pos = pos
樂趣;樂趣。長度= 1;
}
else if(IsBlank(s))
an . blank++;
else if(begin){
樂趣;樂趣。長度++;
如果(找到(s," { "!=-1) //檢查是否進入了函數體。
{
c++;
start = TRUE
}
if(找到(s,“}”)!= -1)//檢測函數是否結束。
c-;
if(c = = 0 & amp;& amp開始)
{
begin = FALSE
start = FALSE
}
}
其他
an . others++;
}
fclose(FP);//關閉分析文件
}
fclose(fpp);//關閉日誌文件
an . funcount = j+1;//保存函數個數
打印(& amp安);//打印分析結果
}
voidmain()
{
int n,I;
char c;
char文件名[計數][長度];
printf(" \ t-\ n ");
Printf("\t程序源代碼分析軟件沈航電子信息工程研究所-王攀\ n ");
printf(" \ t-\ n ");
while(1){
n = 0;
Printf ("\ t \ t * * * * * * *程序分析* * * * * * * * \ n ");
Printf("請輸入要分析的源文件數:");
而(!GetIn(& amp;n)| | n & lt;= 0){
Printf("請輸入要分析的源文件數:");
}
for(I = 0;我& ltn;i++)
{
printf(" \ n請輸入%d源文件:",I+1);
scanf("%s ",文件名[I]);
checkfile(文件名[i],I);
fflush(stdin);
}
analy(文件名,n);
Printf ("\ t * * * * * *是否要繼續使用此軟件?y/N * * * * * * * * * * * * \ N ");
c = getchar();
if(c == 'Y' || c == 'y ')
繼續;
打破;
}
}