1) 问题描述: 读入一个(最多9个)C程序代码文件,统计程序中代码、注释和空行数以及函数的个数,显示函数名并生成相应的记录日志。
2) 基本要求如下:
(1)、把程序文件(如.c或者.txt等)按字符顺序读入源程序;
(2)、输入正确性检查;
(3)、边读入程序,边识别统计代码行、注释行和空行,同时还要识别函数,统计代码个数;
(4)、最多允许一次分析9个文件
2 显示结果
备注:本文的代码试验IDE为VS2013。本代码对比较常规的编程习惯下编写的C代码可以比较好的识别,但是对一些特殊情况不能识别。
1)输入正确的文件个数和路径
2)输入正确时生成的日志文件

3 程序结构
1)整体结构

2)分析模块结构

4 源代码
整个工程共有三个文件构成:statist.h;source.c;main.c

1) statist.h
#define SIZE_N 100 #define SIZE_L 200 #define NUM_F 9 #define title "------------------------Life is a Fight-----------------------------------" extern bool com_flag; void getline(FILE* pfile, char* pt); char* clearblank(char*pt); char* mystrstr(char* s1, char* s2); bool Isblank(char* pt); int Iscom(char* pt); bool Isfunc(char* pt); bool Qtycheck(int* pt);
讯享网
2) source.c
讯享网#include<stdio.h> #include<string.h> #include<stdbool.h> #include"statist.h" void getline(FILE* pfile,char* pt) { while (!feof(pfile)) { *pt = fgetc(pfile); if (*pt=='\n') //成功读取完一行,直到换行符 { *pt = '\0'; return; } pt++; } *pt = '\0'; //如果还没有检测到换行符,文件已经结束,则在末尾添加终止符 } char* clearblank(char* pt) { while ((*pt == ' ') || (*pt == ' ')) { pt++; } return pt; } char* mystrstr(char* s1, char* s2) { char*s, *sp1, *temp1, *temp2; int q_flag = 0; if (strstr(s1, "\"") == NULL) //如果没有发现引号 { s = strstr(s1, s2); return s; } else //如果发现引号 { sp1 = s1; while (*sp1) { temp1 = strstr(sp1, "\""); temp2 = strstr(sp1, s2); if ((temp1 != NULL) && (temp1 == sp1)) { if (q_flag == 0) q_flag = 1; else q_flag = 0; } if ((temp2 != NULL) && (q_flag == 0) && (temp2 == sp1)) return sp1; sp1++; } return NULL; } } bool Isblank(char* pt) { clearblank(pt); if (*pt == '\0') return 1; return 0; } int Iscom(char* pt) { char* pt1,*pt2,*pt3; clearblank(pt); pt1 = mystrstr(pt, "//"); pt2 = mystrstr(pt, "/*"); pt3 = mystrstr(pt, "*/"); if (com_flag == 0) { if ((pt2!=NULL) && (pt3 == NULL)) //如果只有/*表明注释开始 com_flag = 1; if (pt1 == pt) //双斜杠开头的注释 return 1; else if (pt1 - pt > 0 || pt2 - pt > 0) //有注释符号,但是不是顶头开始 return 2; else if ((pt2 == pt) && ((pt3 != NULL && (*(pt3 + 2) == '\0')) || (pt3 == NULL))) //以/*开头以*/结尾,或者以/*开头,没有检测到*/ return 1; else if ((pt2 == pt) && (pt3 != NULL) && (*(pt3 + 2) != '\0')) //以/*开头但是没有以*/结尾 return 2; else if (pt1 == NULL || pt2 == NULL) //没有检测到注释符号 return 0; } else if (com_flag == 1) { if (pt3!=NULL) { com_flag = 0; return 1; } printf("\nYYYY\n"); return 1; //如果com_flag==1,且没有检测到*/则是一句注释 } } bool Isfunc(char* pt) { char* pt1, *pt2, *pt3,*pt4,*pt5,*pt6; clearblank(pt); pt1 = mystrstr(pt, "("); pt2 = mystrstr(pt, ";"); pt3 = mystrstr(pt, "if"); pt4 = mystrstr(pt, "while"); pt5 = mystrstr(pt, "for"); pt6 = mystrstr(pt, "switch"); if (pt1 != NULL&&pt2 == NULL&&pt3 == NULL&&pt4 == NULL&&pt5 == NULL&&pt6 == NULL) return true; return false; } bool Qtycheck(int* pt)//只允许输入一个1到9的数字 { char temp[3]; char c; fflush(stdin); gets(temp); if (temp[0]>'0'&&temp[0] <= '9'&&temp[1] == '\0') *pt = (int)(temp[0] - 48); else { fflush(stdin); printf("Please re-enter the file quantity(0<n<10):"); return 0; } return 1; }
3) main.c
#include<stdio.h> #include<string.h> #include<stdbool.h> #include"statist.h" #include<stdlib.h>//system()的头文件 #include<malloc.h> bool com_flag; int main(void) { FILE* in,*log; char con; char temp[SIZE_L + 1]; char name[SIZE_N]; char* pt; char* name_t; int* result; int n = 0; struct FIL{ int cod; int blk; int com; int fct; }fil = { 0, 0, 0, 0 }; com_flag = 0; do{ printf("%s", title); printf("\n\n\nPlease enter the file quantity(0<n<10):"); while (!Qtycheck(&n)); name_t = (char*)malloc(n*sizeof(name)); result = (int*)malloc(n * 4 * sizeof(int)); log = fopen("log.txt", "w"); fprintf(log, "%s\n\n\n", title); for (int i = 0; i < n; i++) { printf("please enter file \"%d\" name:", i + 1); scanf("%s", name_t + i*SIZE_N); in = fopen(name_t + i*SIZE_N, "r"); while (!in) { fflush(stdin); printf("please re-enter file \"%d\" name:", i + 1); scanf("%s", name_t + i*SIZE_N); in = fopen(name_t + i*SIZE_N, "r"); } fclose(in); } for (int i = 0; i < n; i++) { in = fopen(name_t + i*SIZE_N, "r"); while (!feof(in)) { getline(in, temp); pt = clearblank(temp); if (Isblank(pt) == 1 && com_flag == 0) { fil.blk++; continue; } else if (Iscom(pt) == 1) { fil.com++; continue; } else if (Iscom(pt) == 2 && Isfunc(pt) == 0) fil.com++; else if (Iscom(pt) == 2 && Isfunc(pt) == 1) { fil.com++; fil.fct++; fil.cod++; fprintf(log, "%s %s\n", name_t + i*SIZE_N, temp); continue; } else if (Isfunc(pt) == 1) { fil.fct++; fprintf(log, "%s %s\n", name_t + i*SIZE_N, temp); } fil.cod++; } *(result + 4 * i) = fil.blk; *(result + 4 * i + 1) = fil.cod; *(result + 4 * i + 2) = fil.com; *(result + 4 * i + 3) = fil.fct; fil.blk = 0; fil.cod = 0; fil.com = 0; fil.fct = 0; com_flag = 0; fclose(in); if (fil.fct) fprintf(log, "\n\n\n"); } fprintf(log, "%s", "\n\n\n=========================================================="); printf("=========================================================="); printf("\nFile No. Blank Code Commen Function\n"); fprintf(log, "\n%s\n", "File No. Blank Code Commen Function"); for (int i = 0; i < n; i++) { printf("%d %d %d %d %d\n", i + 1, *(result + 4 * i), *(result + 4 * i + 1), *(result + 4 * i + 2), *(result + 4 * i + 3)); fprintf(log, "%d %d %d %d %d\n", i + 1, *(result + 4 * i), *(result + 4 * i + 1), *(result + 4 * i + 2), *(result + 4 * i + 3)); } fclose(log); free(name_t); free(result); printf("\n\n\nPress 'Y' to continue\n"); fflush(stdin); con = getchar(); printf("\n\n\n"); } while (con=='Y'||con=='y'); system("pause"); return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/11283.html