软工作业(一):wc程序

github项目传送门:https://github.com/NgYanYee/WC

项目相关要求

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

遇到的困难及解决方法

  • 困难描述

  1. 语言选择:第一时间感觉这个项目该用C语言或者Java来做,但是自己本身对这两个语言都不是特别熟悉,很多人使用的python我并没有学过,而自己比较熟悉的是脚本语言JavaScript,但JavaScript实现起来会比前两种语言要麻烦,最终选择了Java。
  2. 项目设计:之前也有用Java写过一点东西,但是没有写过这类型的,该怎么按逻辑去分类是一个问题。
  • 做过哪些尝试

  根据项目主要功能去网上查询实现功能用到的一些类和方法,遇到自己没有接触过的方法就去了解实现功能与原理。

  • 是否解决

  基本解决

  • 有何收获

  1. 面对新东西时的快速理解和学习能力。
  2. 对Java这门语言的应用能力。
  3. 自己面对一个个人项目时的时间分配能力。

设计说明

  

 

关键代码

  1. 根据是否含有-s命令分类讨论

//识别命令是否包含-s命令
String commandList[] = command.nextLine().split("\\s");
            
            boolean hasSArg = Arrays.asList(commandList).stream().anyMatch(s -> s.equals("-s"));
            if(hasSArg) {
                String pathname = commandList[commandList.length - 2];
                String fileFilter = commandList[commandList.length - 1];
                List<String> paths = new ArrayList<String>();
                paths = getAllFilePaths(new File(pathname), paths, fileFilter);
                if(paths != null) {
                    for(int i = 0; i < paths.size(); i++) {
                        operation(paths.get(i), commandList);
                    }
                }
                
            } else {
//                System.out.println("不含有s");
                operation(commandList[commandList.length - 1], commandList);
            }

  2. 找到目录下所有符合条件的文件

private static List<String> getAllFilePaths(File basePath,List<String> filePaths,String fileFilter){    
        File[] files = basePath.listFiles();
        if(files == null) {
            System.out.println("该目录下无文件,请检查命令格式");
            return filePaths;
        }
        for(File f:files) {
            if(f.isDirectory()) {
//                找到文件夹,继续寻找下一目录
                getAllFilePaths(f, filePaths, fileFilter);
            } else {
                if((f.getName() == fileFilter) || f.getName().endsWith(fileFilter)) {
                    //找到匹配文件,添加到路径数组
                    filePaths.add(f.getPath());
                }
            }
        }
        return filePaths;
    }

  3. 读取文件

InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "utf-8");
BufferedReader bReader = new BufferedReader(isr);

  4. 基本功能

String string = null;
while((string = bReader.readLine()) != null) {
    string = string.trim();
    count += string.length();
}   
boolean blank = true;
String string = null;
while((string = bReader.readLine()) != null) {
    string = string.trim();
    for (char c : string.toCharArray()) {
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){
               if (blank){
                   blank = false;
                   count++;
                }
        }else if (
               c == '-' && !blank){
        }else {
               blank = true;
        }
    }
} 
while(bReader.read()!= -1) {
    String string = bReader.readLine();
    count++;
}

  5. 拓展功能

public static void codeCount(String filePath) {
        int code = 0;
        int codeComments = 0;
        int codeBlanks = 0;
        
        try {
            InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath));
            BufferedReader bReader = new BufferedReader(isr);
            boolean comm = false;
            String s = null;
            while((s = bReader.readLine()) != null) {
                if(s.startsWith("/*") && s.endsWith("*/")) {
                    codeComments++;
                } else if(s.trim().startsWith("//")) {
                    codeComments++;
                } else if(s.startsWith("/*") && !s.endsWith("*/")) {
                    codeComments++;
                    comm = true;
                } else if(!s.startsWith("/*") && s.endsWith("*/")) {
                    codeComments++;
                    comm = false;
                } else if(comm) {
                    codeComments++;
                } else if(s.trim().length() < 1) {
                    codeBlanks++;
                } else {
                    code++;
                }    
            }
            
            isr.close();
            System.out.println("代码行数: " + code);
            System.out.println("注释行数: " + codeComments);
            System.out.println("空行数: " + codeBlanks);
        } catch (Exception e) {
            // TODO: handle exception
        }
    } 

 

测试运行

 

PSP开发耗时

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30  60

· Estimate

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

 20  10

Development

开发

 670  600

· Analysis

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

 120 200

· Design Spec

· 生成设计文档

 60  40

· Design Review

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

 30  20

· Coding Standard

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

 30  30

· Design

· 具体设计

 120  60

· Coding

· 具体编码

 210  180

· Code Review

· 代码复审

 40  30

· Test

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

 60  40

Reporting

报告

 100  120

· Test Report

· 测试报告

 40  40

· Size Measurement

· 计算工作量

 30  30

· Postmortem & Process Improvement Plan

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

 30  40

合计

  800 780
posted @ 2018-09-14 21:09  YanYee12  阅读(155)  评论(0编辑  收藏  举报