WC个人项目(Java)

WC.exe

GitHub链接:https://github.com/yeyuyu/ruanjiangongcheng

1.项目要求

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

具体功能要求:
程序处理用户需求的模式为:

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

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

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

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

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

[file_name]: 文件或目录名,可以处理一般通配符。

高级功能:(未完成)

 -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。

需求举例:
  wc.exe -s -a *.c

返回当前目录及子目录中所有*.c 文件的代码行数、空行数、注释行数。

2.解题思路

  太久没有打代码,看到题目后去网上搜了很多开源代码,但不允许copy,就理解了几份开源代码的思路,再整合为自己用,设计了基本模块和框架。接着分两大类,先是写出main函数中基本功能的函数,再在control类具体实现出来。后面又补充-s功能和-a功能。

3.设计实现过程

  代码分成两个类:

  1.Main类实现输入命令。

  2.Control类实现基本功能,-s功能,-a功能。

4.关键代码

4.1 main类

public static void main(String[] args) {
        System.out.println("----------------------命令格式----------------------");
        System.out.println("-c [文件路径]  \\返回字符数");
        System.out.println("-w [文件路径]  \\返回词的数目");
        System.out.println("-l [文件路径]  \\返回行数");
        System.out.println("-a [文件路径]  \\返回空行、代码行、注释行的数目");
        System.out.println("-s [文件路径]  \\递归处理目录下符合条件的文件");
        System.out.println("----------------------------------------------------");
        System.out.print("输入命令:");
        Scanner input = new Scanner(System.in);
        String in = input.nextLine();
        control cont=new control();
        try {
            cont.sort(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

4.2 基本功能

//统计字符数
   void charcount(String filename) throws IOException{
       BufferedReader brin = new BufferedReader(new FileReader(filename));
       String str1="";
       while ((str1=brin.readLine())!=null){
           charnums+=str1.length();
       }
       System.out.println("字符数为:"+charnums);
       brin.close();
   }
   //统计行数
   void rowcount(String filename) throws IOException{
       BufferedReader brin = new BufferedReader(new FileReader(filename));
       String str1="";
       while ((str1=brin.readLine())!=null){
           rownums+=1;
       }
       System.out.println("行数为:"+rownums);
       brin.close();
   }
   //统计词数
   void wordcount(String filename) throws IOException{
       BufferedReader brin = new BufferedReader(new FileReader(filename));
       String str1="";
       int flag=0;//单词是否连续
       while ((str1=brin.readLine())!=null){
           for(int i=0;i<str1.length();i++){
               if(str1.charAt(i)>='a'&&str1.charAt(i)<='z'||str1.charAt(i)>='A'&&str1.charAt(i)<='Z'){
                   flag=1;
               }
               else{
                   if(flag==1){
                       wordnums++;
                       flag=0;
                   }
               }
           }
       }
       System.out.println("单词数为:"+wordnums);
       brin.close();
   }

4.3 -s功能

   //递归操作
   void readDirectory(String filename1){
       String path="";
       int i=0;
       String []  strs=filename1.split("\\\\");
       String filename=strs[strs.length-1];
       for(;i<strs.length-2;i++){
           path+=strs[i]+"\\";
       }
       path+=strs[i];
       
       
       if(0==filename.compareTo("*.*")||0==filename.compareTo("*.?")||0==filename.compareTo("?.*")){
           File filedirectory = new File(path);
            if (filedirectory.exists()) {
                 File[] files = filedirectory.listFiles();
                 if (null == files || files.length == 0) {
                        System.out.println("文件夹是空的!");
                        return;}
                 else{
            for (File file : files) {
                //遍历路径里的文件夹
                if (file.isDirectory()) {
                    System.out.println(file.getName()+"[文件夹]");
                    readDirectory(file.getAbsolutePath()+"\\"+filename);
                } else {
                    System.out.println(file.getName());
                    try {
                        charcount(file.toString());
                        wordcount(file.toString());
                        rowcount(file.toString());
                        allcount(file.toString());
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("总字符数为:"+charnums);
                    System.out.println("总词数为:"+wordnums);
                    System.out.println("总行数为:"+rownums);
                    System.out.println("总空行数为:"+emptyrownums);
                    System.out.println("总代码行数为:"+coderownums);
                    System.out.println("总注释数为:"+noterownums);
                }
            }
       }
                 }
            else{
                System.out.println("文件不存在!");
            }
       }
       else{
       String filenamesort []=filename.split("\\.");
       if(filenamesort[0].equals("*")){
       String filename2="."+filenamesort[filenamesort.length-1];
            File filedirectory2 = new File(path);
            if (filedirectory2.exists()) {
                File[] files2 = filedirectory2.listFiles();
                if (null == files2 || files2.length == 0) {
                    System.out.println("文件夹是空的!");
                    return;
                } else {
                    for (File file2 : files2) {
                         //遍历路径里的文件夹
                        if (file2.isDirectory()) {  
                            readDirectory((file2.getAbsolutePath()+"\\"+filename2));
                        } else if (file2.getName().contains(filename2)) {
                              System.out.println(file2.getName());
                            try {
                                charcount(file2.toString());
                                wordcount(file2.toString());
                                rowcount(file2.toString());
                                allcount(file2.toString());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            System.out.println("总字符数为:"+charnums);
                            System.out.println("总词数为:"+wordnums);
                            System.out.println("总行数为:"+rownums);
                            System.out.println("总空行数为:"+emptyrownums);
                            System.out.println("总代码行数为:"+coderownums);
                            System.out.println("总注释数为:"+noterownums);
                        }
                    }
                }
            } else {
                System.out.println("文件不存在!");
            }
       } 
       else if(filenamesort[filenamesort.length-1].equals("*")){
           File filedirectory3 = new File(path);
            if (filedirectory3.exists()) {
                 File[] files3 = filedirectory3.listFiles();
                 if (null == files3 || files3.length == 0) {
                        System.out.println("文件夹是空的!");
                        return;
                    } else {
            for (File file3 : files3) {
                //遍历路径里的文件夹
                if (file3.isDirectory()) {
                    System.out.println(file3.getName()+"[文件夹]");
                    readDirectory(file3.getPath()+"\\"+filename);
                } else {
                    if(file3.getName().indexOf(filenamesort[0])==0){
                        System.out.println(file3.getName());
                        try {
                            charcount(file3.toString());
                            wordcount(file3.toString());
                            rowcount(file3.toString());
                            allcount(file3.toString());
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("总字符数为:"+charnums);
                        System.out.println("总词数为:"+wordnums);
                        System.out.println("总行数为:"+rownums);
                        System.out.println("总空行数为:"+emptyrownums);
                        System.out.println("总代码行数为:"+coderownums);
                        System.out.println("总注释数为:"+noterownums);
                    }
                }
            }
       }
                 }
            else {
                System.out.println("文件不存在!");
            }
            }
       
       
      }
   }

4.4 -a功能

   //统计空白,注释,代码行数
   void allcount(String filename) throws IOException{
       BufferedReader brin = new BufferedReader(new FileReader(filename));
       String str1="";
       int linenums=0;
       while ((str1=brin.readLine())!=null){
           if(str1.length()==0||str1.length()==1){
               emptyrownums++;
           }
           else{
               for(int i=0;i<str1.length()-1;i++){
                   if(str1.charAt(i)== '\\' &&str1.charAt(i+1)=='\\'){
                       if(i==0||i==1){
                           noterownums++;
                       }
                   }
               }
           }
           linenums++;
       }
       if(linenums<noterownums+emptyrownums)coderownums=0;
       else{coderownums=linenums-noterownums-emptyrownums;}
       System.out.println("注释行数为:"+noterownums);
       System.out.println("空行数为:"+emptyrownums);
       System.out.println("代码行数为:"+coderownums);
       brin.close();
   }

 

5.测试

5.1 空文件

 

5.2 只有一个字符的文件

 

5.3 只有一个词的文件

 

5.4 只有一行的文件

 

5.5 源文件

 

5.6 -s 功能

5.7 代码覆盖率

 

6.PSP

PSP

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30  30

· Estimate

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

 30  30

Development

开发

 1130  1260

· Analysis

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

 240  200

· Design Spec

· 生成设计文档

 60  90

· Design Review

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

 30  30

· Coding Standard

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

 60  30

· Design

· 具体设计

 120  60

· Coding

· 具体编码

 300  360

· Code Review

· 代码复审

 120  100

· Test

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

 120  300

Reporting

报告

120   60

· Test Report

· 测试报告

 60  30

· Size Measurement

· 计算工作量

 30  15

· Postmortem & Process Improvement Plan

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

30   15

合计

   1280  1350

7.项目总结

  项目开始遇到很多困难:

  1)不会使用Git,刚开始注册GitHub就遇到很多问题,一一百度花了很长时间。刚开始不懂仓库怎么创建,也不知道怎么push上去。后面百度Git教程,粗略学了一下Git的教程,用Git Bush使用命令操作,相对简单。

  2)刚开始是模仿几份代码的思路,由于部分思路没有缕清,尝试了多次才吧正确的代码写出来;并且在打码过程中犯了很多低级错误。编码是整个工程耗时最长的部分。

  3)没有接触过测试单元,学习如何写测试单元花了一些时间。

  之前打码并没有一个完整的流程,这次首次用软件工程思想做一个小项目,虽然做的结果差强人意,用软件工程思想做出来的小项目有点也没有凸显出来,但总是是打开了软件工程的大门。

  

 

posted on 2018-09-14 23:05  十分机智y  阅读(114)  评论(0编辑  收藏  举报

导航