0、外部接口:command file.c outfile.txt 1、统计模块:
函数:void CodeStat(FILE* infp)
功能:统计出总行数、代码行数、空行数、注释行数 输入参数:infp:文件指针,指向被统计的文件 输出参数:无 返回:无
调用的全局变量:CodeNum:代码行数 PlantNum:空行数 AnotNum:注释行数 TotalNum:总行数
2、输出模块:
函数:void OutPut(File* outfp)
功能:把四个全局变量代码行数、空行数、注释行数、总行数输出到outfp指向的文件
输入参数:outfp:指向数据的文件 输出参数:无 返回:无
调用的全局变量:CodeNum:代码行数 PlantNum:空行数 AnotNum:注释行数 TotalNum:总行数
二、详细设计:
1、统计模块:(此方法不考虑printf(“/*„„*/”)的情况)
void CodeStat(FILE* infp)
int AnotFlag = 0;//注释标志,当注释为/*„„*/时,使用此标志 char ch;
char ch_front;
初始化代码行数CodeNum为0; 初始化空行数PlantNum 为0; 初始化注释行数AnotNum 为0; 初始化注释行数TotalNum 为0;
if(infp 为空)
打印打开文件input错误; return; fseek(infp,0,0); ch = fgetc(infp); if(ch为 EOF) return; fseek(infp,0,0); while(非文件结束)
TotalNum++ ch = fgetc(infp);
while(ch == ' ' || ch == 9)//滤掉空格和TAB键 ch = fgetc(infp);
if滤掉空格后的首字符为回车或文件结束符 PlantNum++;
else if(注释标志AnotFlag为 1) AnotNum++;
while(ch != '\\n' && ch != EOF)
//判断最后一次读到的ch是否是\"/\";
//如果是,则“/* */”注释结束,注释标志需置成0
if ch == '/'
if ch_front == '*' AnotFlag = 0; else if ch为字符“*”
ch = fgetc(infp); if ch为字符'/'
置注释标志AnotFlag 为0;
//如果注释标志为0,则表示注释结束,后面可以有代码 if 注释标志AnotFlag 为0 //后面可能还有代码 ch = fgetc(infp);
while(ch == ' ' || ch == 9 )//滤掉“*/”后面的空格和TAG键 ch = fgetc(infp);
如果 ch != '/' 且 ch != '\\n' 且 ch != EOF CodeNum++;
继续读本行,直到本行结束;
//如果ch不是回车符和文件结束符,表示需要继续while循环 if(ch != '\\n' && ch != EOF)//加此,因为上面可能出现读到回车符 ch_front = ch;
ch = fgetc(infp);
else if注释标志为0,且非空格首字符不是“/” CodeNum++;
while(ch != '\\n' && ch != EOF) ch = fgetc(infp); if(ch为 '/')
ch = fgetc(infp); if(ch 为 '/')
AnotNum++;
继续读本行,直到本行结束; else if(ch 为 '*') AnotNum++; AnotFlag = 1;
ch_front = ' ';//此处可以赋值为除*以外的任何符号
while(ch != '\\n' || ch != EOF) ch = fgetc(infp);
if(ch == '/' && ch_front =='*')
AnotFlag = 0; else
ch_front = ch;
else if非空格首字符为“/” ch = fgetc(infp); if(ch 为 '/')
AnotNum++;
继续读本行,直到本行结束; else if(ch 为 '*') AnotNum++; AnotFlag = 1;
while(ch != '\\n' || ch != EOF) ch = fgetc(infp); if(ch 为 '*')
ch = fgetc(infp); if(ch 为 '/')
AnotFlag = 0; // “/* */”注释结束 else if(AnotFlag == 0) ch = fgetc(infp);
while(ch == ' ' || ch == 9) ch = fgetc(infp);
if(ch != '/' && ch != '\\n' && ch != EOF) CodeNum++;
继续读本行,直到本行结束;
2、输出模块:
void OutPut(FILE* outfp) { if(outfp 为空)
打印outfp参数为空; return;
fprintf(outfp, \"\\n-----------------------------------------\"); fprintf(outfp, \"\\n文件总行数:\"); fprintf(outfp, \"%d \ fprintf(outfp, \"\\n代码行数:\");
}
fprintf(outfp, \"%d \fprintf(outfp, \"\\n注释行数:\"); fprintf(outfp, \"%d \fprintf(outfp, \"\\n空行数:\"); fprintf(outfp, \"%d \
fprintf(outfp, \"\\n-----------------------------------------\");
3、主函数:
void main(int argc, char* argv[]) {
FILE *infp, *outfp; if(argc <= 2)
打印命令参数个数错误; exit(1);
if((infp = fopen(argv[1], \"r+\")) == NULL) 打印读文件打开错误; exit(1);
if((outfp = fopen(argv[2], \"w+\")) == NULL) 打印写文件打开错误; exit(1);
CodeStat(infp); OutPut(outfp);
关闭infp; 关闭outfp; }
因篇幅问题不能全部显示,请点此查看更多更全内容