• 个人项目:Word Count


    GitHub地址:https://github.com/Guyuefangzheng/Word-Count

    项目要求

    wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。

    实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
    具体功能要求:
    程序处理用户需求的模式为:

    wc.exe [parameter] [file_name]

    基本功能列表:

    wc.exe -c file.c //返回文件 file.c 的字符数 (实现)

    wc.exe -w file.c //返回文件 file.c 的词的数目 (实现)

    wc.exe -l file.c //返回文件 file.c 的行数 (实现)

    扩展功能:
    -s 递归处理目录下符合条件的文件(实现)
    -a 返回更复杂的数据 (实现)

    2、psp表

    *PSP2.1* *Personal Software Process Stages* *预估耗时(分钟)* *实际耗时(分钟)*
    Planning 计划 60 30
    ·Estimate · 估计这个任务需要多少时间 60 30
    Development 开发 1220 870
    · Analysis · 需求分析 (包括学习新技术) 150 180
    · Design Spec · 生成设计文档 40 20
    ·Design Review · 设计复审 (和同事审核设计文档) 40 20
    ·Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 20
    · Design · 具体设计 60 60
    · Coding · 具体编码 400 360
    · Code Review · 代码复审 100 60
    · Test · 测试(自我测试,修改代码,提交修改) 200 150
    Reporting 报告 120 90
    · Test Report · 测试报告 60 30
    ·Size Measurement · 计算工作量 30 30
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 30
    合计 1200 990

    3、解题思路

    ​ 一开始看到题时想的是用c来实现还是用Java,最后还是选择了熟悉的c。这次的题目涉及到的知识点命令行参数、文件操作这两部分以前没有去深究,因为书都在学校,所以面向搜索引擎来学习这部分的内容。

    4、设计实现过程

    ​ 每一个功能一个函数,再加上一个main函数一共六个函数,在这几个功能模块中WordCount()调用CharCount()来判断该文件是否为空,SearchFile()调用三个基础功能的函数来实现批量操作。

    5、代码说明

    头文件

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<io.h>
    #include<time.h>
    

    基本功能:获取字符数

    int CharCount(char *file){	//字符数统计 
    	FILE *fp = NULL;
    	fp = fopen(file,"r");
    	if(fp==NULL){
    		printf("没有找到此文件!
    ");
    		exit(-1);
    	}
    	
    	int Ccount = 0;
    	char temp;
    	while(!feof(fp)){	//文件结束判断 
    		temp = fgetc(fp);
    		if(temp!=' '&&temp!='
    '&&temp!='	'&&temp!=EOF)
    			Ccount++;
    	} 
    	fclose(fp);
    	return Ccount; 
    }
    

    首先判断该文件是否存在,不存在就退出,不是一个有效字符有四种情况:空格、换行、缩进格、txt文件结束符。

    .
    基本功能:获取词数

    int WordCount(char *file){	//词数统计 
    	if(CharCount(file)==0)
    		return 0;
    		
    	int Wcount = 0;
    	bool b = 0;	//用来标记是否是字符 
    	char temp;
    	FILE *fp = NULL;
    	fp = fopen(file,"r");
    	while(!feof(fp)){
    		temp = fgetc(fp);
    		if(temp==' '||temp=='	'||temp=='
    '||temp==EOF){	//四种情况,包括文件结束 
    			if(b==1){	 //前面是字符,词数+1 
    				Wcount++;
    				b = 0;
    			}
    		} 
    		else
    			b = 1;	//如果是字符,b标记为1 
    	}
    	fclose(fp);
    	return Wcount;
    }
    

    通过调用字符统计函数来判断该文件是否存在和是否为空,用一个bool变量来标记,当bool值为1时词数加一。

    .
    基本功能:获取行数

    int LineCount(char *file){	//行数统计 
    	FILE *fp = NULL;
    	fp = fopen(file,"r");
    	if(fp==NULL){
    		printf("没有找到此文件!
    ");
    		exit(-1);
    	}
    	
    	int Lcount = 1;
    	char temp;
    	while(!feof(fp)){
    		temp = fgetc(fp);
    		if(temp=='
    ')
    			Lcount++;
    	}
    	fclose(fp);
    	return Lcount;
    }
    

    行数初始为1,遇到 加1。

    .
    扩展功能:处理目录下符合条件的文件

    int SearchFile(){	//处理目录下符合条件的文件
        struct _finddata_t fileinfo;	//文件存储信息结构体 
        long fHandle;	//保存文件句柄
        int t=0;	//文件数记录器
        fHandle = _findfirst("*.txt",&fileinfo);	//查找当前目录下的txt文件
    	 
        if(fHandle==-1L)
        	printf( "当前目录下没有txt文件
    ");
        else
        	do{
        		t++; 
        		printf("找到文件:%s
    ",fileinfo.name);
        		printf("字符数为:%d
    ",CharCount(fileinfo.name));
        		printf("词数为:%d
    ",WordCount(fileinfo.name));
        		printf("行数为:%d
    
    ",LineCount(fileinfo.name));
    		}while(_findnext(fHandle,&fileinfo)==0);
    		_findclose(fHandle);	//关闭文件链接
    		return t; 
    }
    

    通过头文件io.h中的文件结构体 _finddata_t ,使用 _findfist 和 _findnext 两个函数来查找文件,找到文件,调用基础模块。

    .
    扩展功能:返回更复杂的数据(代码行 / 空行 / 注释行)

    int MoreLine(char *file){	//返回更复杂的数据(代码行 / 空行 / 注释行)
    	FILE *fp = NULL;
    	fp = fopen(file,"r");
    	if(fp==NULL){
    		printf("没有找到此文件!
    ");
    		exit(-1);
    	}
    	
    	int nNum = 0,cNum = 0,aNum = 0;
    	bool b = 0;	// 
    	int c;
    	char temp;
    	while(!feof(fp)){
    		temp = fgetc(fp);
    		if(temp=='
    '||temp==EOF){	//换行或者文件结束 
    		//在换行或者文件结束时判断出类型 
    			if(c==0)	//空行 
    				nNum++;
    			else if(c==1){	//代码行 
    				cNum++;
    				c = 0;
    			}
    			else{	//注释行 
    				aNum++;
    				c = 0;
    			}
    		}
    		else if(temp!=' '&&temp!='	'&&temp!='{'&&temp!='}'){
    			//判断出代码行和注释行,剩下的即是空行 
    			if(temp=='/'){
    				if(c==0&&b==0)
    					b = 1;
    				else if(c==0&&b==1){
    					c = 2;
    					b = 0;
    				}
    			} 
    			else if(c!=2)
    				c = 1;	 
    		}
    	}
    	fclose(fp);
    	printf("空行数为:%d
    ",nNum);
    	printf("代码行数为:%d
    ",cNum);
    	printf("注释行数为:%d
    ",aNum);
    	return nNum+cNum+aNum;
    }
    

    //设置两个标记变量,一个整形变量用0,1,2来标记该行是空行、代码行还是注释行,一个bool变量用来判断注释行。标记所有的代码行和注释行,剩下的就都是空行了。

    .
    main函数

    int main(int argc,char *argv[]){
    	clock_t start_t,finish_t;
    	double Total_time;
    	start_t = clock();
    	if(!strcmp(argv[1],"-c"))
    		printf("charnumber: %d
    ",CharCount(argv[2]));
    	else if(!strcmp(argv[1],"-w"))
    		printf("wordnumber: %d
    ",WordCount(argv[2]));
    	else if(!strcmp(argv[1],"-l"))
    		printf("linenumber: %d
    ",LineCount(argv[2]));
    	else if(!strcmp(argv[1],"-s"))
    		printf("find txt number: %d
    ",SearchFile());
    	else if(!strcmp(argv[1],"-a"))
    		MoreLine(argv[2]);
    	else{ 
    		printf("请输入正确的指令!
    ");
    		exit(1);
    	}
    	finish_t = clock();
    	Total_time = (double)(finish_t - start_t) / CLOCKS_PER_SEC;//将时间转换为秒
    	printf("%f seconds
    ",Total_time);
    }
    

    用头文件time.h中的 clock_t 函数来计算时间。

    6、测试运行

    7、项目小结

    1、这次项目暴露出了我其实对c语言还只是处于最基础的了解,文件操作、时间函数都不熟悉,都是现找现做的,需要加深学习
    2、没能对项目的完成时间有个正确的预估,对如何估算PSP的时间还需学习
    3、查资料的时候注意到一点,feof(FILE *fp)如果文件结束,则返回非0值,否则返回0,但是读完最后一个字符后,fp->flag仍然没有被设置为_IOEOF,因为还有个文件结束符,直到再次调用fgetc(),feof()才能探测到文件结尾。并且不应用EOF来代替feof(),因为fgetc()返回-1时有两种情况:读到文件结尾或是读取错误。

  • 相关阅读:
    Web负载均衡的几种实现方式
    Apache和Nginx的区别
    Nginx和Apache区别
    Git 使用中显示“Another git process seems to be running in this repository...”问题解决
    上传本地代码到gitHub过程详解
    MySQL数据库中varchar与char类型的区别
    正则表达式中/i,/g,/ig,/gi,/m的区别和含义
    内行看门道:看似“佛系”的《QQ炫舞手游》,背后的音频技术一点都不简单
    惧怕羊毛党?腾讯云为你保驾护航
    教你1天搭建自己的“微视”
  • 原文地址:https://www.cnblogs.com/cheng-/p/12485370.html
Copyright © 2020-2023  润新知