代码改变世界

第一次作业——WordCount的基础功能实现

2018-09-22 18:11  1987kong  阅读(369)  评论(5编辑  收藏  举报

项目的gitee地址: https://gitee.com/kong1987/wc

PSP表格如下

项目需求分析:

(以下为老师提供的需求)

wc.exe -c file.c     //返回文件 file.c 的字符数wc.exe -w file.c     //返回文件 file.c 的单词总数wc.exe -l file.c     //返回文件 file.c 的总行数wc.exe -o outputFile.txt     //将结果输出到指定文件outputFile.txt

注意:

空格,水平制表符,换行符,均算字符。

由空格或逗号分割开的都视为单词,且不做单词的有效性校验,例如:thi#,that视为用逗号隔开的2个单词。

-c, -w, -l参数可以共用同一个输入文件,形如:wc.exe –w –c file.c 。

-o 必须与文件名同时使用,且输出文件必须紧跟在-o参数后面,不允许单独使用-o参数。

参数及其约定如下:

参数名字

参数意义

用法示例

-c[必选]

文件的字符数

示例:wc.exe -c file.c [表示返回文件file.c的字符数,并存储在result.txt中]

-w[必选]

文件单词总数

示例:wc.exe -w file.c [表示返回文件file.c的单词数,并存储在result.txt中]

-l[必选]

文件行数

示例:wc.exe -l file.c [表示返回文件file.c的总行数,并存储在result.txt中]

-o[必选]

输出文件名

示例:wc.exe –c file.c -o outfile.txt [表示返回文件file.c的字符数,并存储在outfile.txt中]

需求分析:

实现wordCount的基础功能:命令 -c 字符数;命令-w 单词数(不做 单词的验证);命令-l 行数;命令-o 输出 ; 输出结果的保存文件xx.txt,并且 -o命令不能与xx.txt分开。如果命令格式不对,输出err.log文件

命令中同时需要输入源代码文件.java,无源文件则不能输出结果,并提示错误。如果命令行中无-o命令, 则默认输出到result.txt文件中。

 如果同时涉及多项统计,如同时需要统计字符、单词和行数,则按照字符-->单词-->行数-->代码行数/空行数/注释行的顺序,依次分行显示。显示顺序与输入参数的次序无关。输入参数顺序不固定。

详细设计 :

本次实现使用java,使用eclipseIDE进行开发。

设置基础功能统计类BaseCount,包括countChar,CountWord,countLine以及outputFile四个方法部分代码如下。

计算字符数:

 1 private int c = -1;
 2     private int w = -1;
 3     private int l = -1;
 4     private File file;
 5 
 6     public int countChar(String file) throws IOException {
 7         this.file = new File(file);
 8         FileInputStream fip = new FileInputStream(this.file);
 9         InputStreamReader reader = new InputStreamReader(fip);
10         StringBuffer sBuffer = new StringBuffer(); 
11         while (reader.ready()) {
12             sBuffer.append((char) reader.read());
13         }
14 
15         c = sBuffer.length();
16         reader.close();
17         fip.close();
18         return c;
19     }

 

 

  new输出文件,并将结果添加到文件中

 

public void outputFile(String file) throws IOException {
        File f = new File(file);
        FileOutputStream fop = new FileOutputStream(f);
        OutputStreamWriter writer = new OutputStreamWriter(fop);
        if (c > 0) {
            writer.append(this.file.getName() + ",字符数:" + c+"\r\n");
        }
        if (w > 0) {
            writer.append(this.file.getName() + ",单词数:" + w+"\r\n");
        }
        if (l > 0) {
            writer.append(this.file.getName() + ",行数:" + l+"\r\n");
        }
        writer.close();
        fop.close();
    }

 


设置主要逻辑处理类Main如下:

   1. 获取输入源文件,并设置flag
           2.获取输出文本,并设置flag

   3.判断-o xx.txt是否一起输入的逻辑

 

private static BaseCount baseCount = new BaseCount();

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        boolean outFileFlag = false;
        boolean inFileFlag = false;
        boolean linkFlag = true;
        String file = new String();
        String outFile = new String();
        for (int i = 0; i < args.length; i++) {
            String tfile = args[i];
            if (tfile.endsWith(".java")) {
                file = "../" + tfile;
                inFileFlag = true;
            }
            if (tfile.endsWith(".txt")) {
                outFile = tfile;
                outFileFlag = true;
            }
            if ((args[i].equals("-o") && i == args.length - 1)) {
                System.err.println("请按格式指定 输出文件!");
                linkFlag = false;
            }
            if (i < args.length - 1) {
                if (!args[i + 1].endsWith(".txt") && args[i].equals("-o")) {
                    System.err.println("请按格式指定 输出文件!");
                    linkFlag = false;
                }
            }
            if (i > 0) {
                if (args[i].endsWith(".txt") && !args[i - 1].equals("-o")) {
                    System.err.println("请按格式输入命令!");
                    linkFlag = false;
                }
            }
        }

 

 

 

  4.循环遍历不同的命令,并调用不同的方法。代码略。
      
代码说明:
将源项目打包为jar文件,再通过exe4j将jar转为.exe文件,通过cmd命令行启动.exe文件并传入命令参数。通过遍历的方式将源程序文件字符串得到,通过设置flag 的方式判断是否输入源程序,如果没有则不能对文件进行操作。通过遍历的方式判断是否有输出文件字符串以及输出命令-o存在,并通过设置outFileFlag以及linkflag 的方式判断是否输入输出文件并且输出文件格式是否与-o命令连用。否则判定为输入格式错误,并且不能执行-w -l -c操作。得到了正确的输入格式之后再次对字符串数组进行便利同时使用switch方法针对不同的命令进行相应的文件操作。如果没有“-o  xx.txt”输入,则默认将结果输出到result.txt文件。

 设置测试过程:

测试单元:new一个测试包,new一个basetest类,并对main中的逻辑过程进行测试,判断结果是否正确。以及对baseCount中的方法进行测试。其中,对于逻辑的测试是最容易出错的,在最初的实现版本中出现了许多的逻辑错误,如下:

args5={"-c","-l","-w","test3.java","-o"};  虽然会出现格式错误提示,但是文件照样生成了。
String[] args6={"-c","-l","-w","test2.java","out3.txt"};  文件照样生成了,没有错误提示。
String[] args6={"-c","-l","-w","-o","test3.java","out3.txt"};  错误提示有,但是文件照样输出,并且是result.txt与out3.txt都输出了。
由于在最初的需求分析阶段没有完全体会到全部的需求,并在设计阶段没有生成设计文档以及设计复审,在后边的代码复审阶段没有尽心,因此才造成了在测试阶段花费了大量的时间。并最终造成了代码逻辑的混乱,可读性极差的结果。

测试代码 (部分)如下:

    @Test
    public void testMain() throws IOException {
        Main m=new Main();
        String[] args={"-c","test1.java"};
        String[] args1={"-c","-w","test2.java"};
        String[] args2={"-c","-l","test3.java"};
        String[] args3={"-c","-l","-w","test1.java","-o","out1.txt"};
        String[] args4={"-c","test1.java","-o","out2.txt"};
        String[] args5={"-c","-l","-w","test3.java","-o"};
        String[] args6={"-c","-l","-w","-o","out3.txt"};
        String[] args7={"-c","-l","-w","test2.java","out3.txt"};
        String[] args8={"-c","-l","-w","-o","test3.java","out3.txt"};
        /*m.main(args);
        m.main(args1);
        m.main(args3);
        m.main(args4);*/
        m.main(args5);
        
    }

 

 

 

实际上整个项目的进行阶段,不只是代码编辑上的问题,还包括新知识的涌入。

新的知识:git代码库管理的学习参考廖雪峰老师:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

exe4j下载:http://download-keycdn.ej-technologies.com/exe4j/exe4j_windows_6_0_1.exe

git建立远程代码库到gitee:https://blog.csdn.net/gxx_csdn/article/details/78906910

git中ssh key生成步骤:https://www.cnblogs.com/horanly/p/6604104.html

Git可视化极简易教程:https://www.runoob.com/w3cnote/git-gui-window.html