wc.exe实现(java)

项目的Github地址:https://github.com/hrzgj/-

一、项目简介

 

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   返回更复杂的数据(代码行 / 空行 / 注释行)。

 

空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。

代码行:本行包括多于一个字符的代码。

注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:

    } //注释
在这种情况下,这一行属于注释行。

 

二、PSP表格

 

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 20

 20

· Estimate

· 估计这个任务需要多少时间

300

 420

Development

开发

 170

 240

· Analysis

· 需求分析 (包括学习新技术)

 30

30

· Design Spec

· 生成设计文档

 10

 10

· Design Review

· 设计复审 (和同事审核设计文档)

 10

 10

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 10

 10

· Design

· 具体设计

 30

 60

· Coding

· 具体编码

 40

 40

· Code Review

· 代码复审

 30

30

· Test

· 测试(自我测试,修改代码,提交修改)

 60

 120

Reporting

报告

30

 30

· Test Report

· 测试报告

10

 10

· Size Measurement

· 计算工作量

 10

 10

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 10

 10

合计

 

 470

 630

 

 

 

三、解题思路

 因为要读取文件的内容,而java封装了很好的io,故使用java来进行编程。需要统计单词,首先想到可以用正则表达式去分割单词,处理一个目录下的文件,可以用递归处理。

 

四、设计实现过程

  根据每个需求来创建一个方法来实现每一个具体的功能,因为有有5个需求,故构建5个方法,分别来实现-w,-c,-l,-s,-a的功能。用主函数调用各个方法。

 

五、代码说明

  首先是主函数获取参数并判断参数是否正确,文件是否存在,再根据输入的参数进行对应的操作

  //统计文件行数
        public static void  countLine (String fileName,String absolutePath) throws Exception {
            BufferedReader br=new BufferedReader(new FileReader(new File(absolutePath)));
            String line =null;
            int sum = 0;
            while((line=br.readLine())!=null) {
                sum++;
            }
            System.out.println((fileName==null?"":fileName)+"文件行数为:"+sum);
        }

        //统计字符数
        public static void  countChar(String fileName,String path) throws Exception {

            BufferedReader br=new BufferedReader(new FileReader(new File(path)));
            int sum = 0 ;
            String line;
            while ((line = br.readLine()) != null){
                sum+=line.length();
            }
            System.out.println((fileName==null?"":fileName)+"文件字符数为:"+sum);

        }

        //统计单词数
        public static void countWord(String fileName,String path) throws Exception {

            BufferedReader br=new BufferedReader(new FileReader(new File(path)));
            //使用正则进行分割:空格 Tab { } ;: ~ ! ? ^ % + - * / | & >> >>> << <<< [ ] ( ) \\
            int countWord = 0;
            String str = "";
            while((str = br.readLine()) != null){
                //这里只使用部分符号,还有更多符号没有进行添加
                countWord += str.split("\\s+|\\(|\\)|,|\\.|\\:|\\{|\\}|\\-|\\*|\\+|;|\\?|\\/|\\\\|/").length;
            }


            System.out.println((fileName==null?"":fileName)+"文件单词数为:"+countWord);
        }


        //递归处理目录的子文件
        public static void countDir(String filePath) throws Exception {
            File dir = new File(filePath);
            if (!dir.isDirectory() || !dir.exists()){
                System.out.println("你指定的不是目录");
                return;
            }
            File[] files = dir.listFiles();
            assert files != null;
            for (File file : files) {
                if (file.isDirectory()){
                    countDir(file.getAbsolutePath());
                }else {
                    String name = file.getName();
                    String absolutePath = file.getAbsolutePath();
                    //调用其他三个方法
                    countLine(name,absolutePath);
                    countChar(name,absolutePath);
                    countWord(name,absolutePath);
                }
            }

        }

        /**
         * 统计空行,代码行,注释行
         */
        public static void countFileSpecialLine(String filePath) throws IOException {
            //空行
            int spaceNum = 0;
            //注释行
            int noteNum = 0;
            //代码行
            int codeNum = 0;
            BufferedReader br=new BufferedReader(new FileReader(new File(filePath)));
            String line;
            while ( (line = br.readLine()) != null){
                String s = line.replaceAll("[\\s;]", "");
                //空行
                if (s.length() == 0){
                    spaceNum++;
                }else if (s.length() == 1 && ("{".equals(s) || "}".equals(s)) ){
                    spaceNum++;
                }
                //注释行
                else if ( (s.startsWith("{") || s.startsWith("}") ) && s.contains("//")){
                    noteNum++;
                }else if (s.startsWith("//")){
                    noteNum++;
                }else if (s.startsWith("/*") && s.length()>=4 && s.endsWith("*/")){
                    noteNum++;
                }else if (s.startsWith("/*")){
                    noteNum++;
                    while (true){
                        if ((line = br.readLine()) != null){
                            noteNum++;
                            if (line.endsWith("*/")) {
                                break;
                            }
                        }else {
                            break;
                        }
                    }
                }else
                    //代码行
                    {
                    codeNum++;
                }
            }
            System.out.println("文件空行数为:"+spaceNum);
            System.out.println("文件注释行数为:"+noteNum);
            System.out.println("文件代码行数为:"+codeNum);
        }

 


六、测试

 

空文件:

 

 

 

一个字符文件:

 

 

一个词文件:

 

 一行的文件:

 

 

源文件:

 

 七,项目小结

预估的时间跟我开发时间相差有点多,在项目开发的时候会出现一些难以预料的bug,做测试的时候花了不少时间。同时对正则表达式的使用不够熟练,需要查阅不少资料才能实现我想要的目的。总的来说,还需不断努力继续学习

 

posted @ 2020-03-22 16:12  hrzgj  阅读(116)  评论(0编辑  收藏  举报