WC 项目要求

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

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

扩展功能:
    -s   递归处理目录下符合条件的文件。
    -a   返回更复杂的数据(代码行 / 注释行)。

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

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

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

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

 


 

 

遇到的困难及解决方法

  • 困难描述 

一开始的时候不知道该选什么语言来实现这个程序,学过C,java,刚接触python。C有点忘了,而且对java的面向对象编程会比较熟悉,比较喜欢,所以选定了java。然后刚开始动手就开始懵了,我要怎么计算字符数?怎么读取文件?不能用ASCII码大于小于来定的吗?怎么这里报错那里又报错?关闭什么流?为什么说我重复报错了?我要读取字节还是字符?拓展功能怎么写?要分包吗?类怎么分?写拓展功能的时候还写着写着电脑中毒了emmmm吓死死了。

  • 做过哪些尝试,是否解决

         我之前上课的java书给师弟了,还好我留了一本师兄给我的《疯狂java讲义》,里面对各种类各种引用以及用法说得非常详细。简单地在网上搜索了一下读取文件要怎么办,发现是要用到IO流的。于是我查了书,看了下,如果是要读取文件字符数的话,要用Reader,字节就要用到InputStream,又查了查,如果是字母,数字这些,多用inputstream来计算,于是就用这个来计算了。然后书上也讲得比较详细,比如File类的用法,访问文件和目录这个可以用到拓展功能-s中,String类的用法就在做拓展功能-a的时候提供了很大的方便。说是说用java,但是写到后面感觉哪里怪怪的,好像在把java当c一样,又没有分类又没有分包,我也不知道该怎么办,不过功能好歹是实现了。中间碰到一些没见过的报错时,会复制一下百度解决方法,比如重复关闭输入流这个,知道了是这个错误后再仔细看看自己代码是不是哪里循环写错了,还是“}”没用对。

       对了,还有写拓展功能的时候,电脑中毒,开机后运行什么都奇慢,尤其是打码的时候,输完一行可能都要等个十几分钟来显示,心态差点就崩了。还好我,机智地,保存了代码后,关机,睡觉。第二天起来杀毒。现在没事啦,流畅多了吼吼!(还一时冲动买了内存条,希望山竹给点面子。。让我先收了货再下雨吧。。。

  • 有何收获

       收获就是,要多看书,多练习,多学多做,知道了怎么用好github,要好好运用百度或者google,然后对java又重拾了信心emmmm不过面对下一个作业还是很悬。。因为跟我组队的同学主C我主Java。。。

 

关键代码or设计说明

 

1 public static void getchars(String filename1) {        
 2         File file = new File(filename1);
 3         if(!file.exists()) {
 4             System.out.println("未找到目标文件。");//指定路径下的文件不存在则输出:未找到目标文件
 5         }else {        
 6         try {
 7             FileInputStream fis=(new FileInputStream(file));
 8             int temp=0;
 9             while ((fis.read()) !=-1) {
10                 temp=temp+1;//每读取一个字符temp+1
11                 }
12             System.out.println("该文件的字符数:"+temp);//输出temp
13             fis.close();//关闭输入流
14         }catch (IOException ex) {
15             ex.printStackTrace();//捕获异常
16         }
17         }
18     }

 

  • 计算字符数,写出这个后往下写就比较顺利了,感觉跟这个再加点东西就ok了

             就一个个地读,读到一个就temp+1

 

public static void getlines(String filename1) {
        File file = new File(filename1);
        if(!file.exists()) {
            System.out.println("未找到目标文件。");//指定路径下的文件不存在则输出:未找到目标文件
        }else {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            int temp=0;
            while ((br.readLine())!= null) {
                temp=temp+1;
            }
            System.out.println("该文件的行数:"+temp);//文件不为空输出temp+1
            br.close();//关闭输入流
        
        }catch (IOException ex) {
            ex.printStackTrace();
        }
        }
      }
  • 了解了Buffered的用法后对它可以一次读一行的算法很感兴趣,感觉用来计算行数很方便又准确,于是把之前的改为这个
public static void getkonglines(String filename1) {
        int dl = 0, kl = 0, zl = 0;
        String t;
        File file = new File(filename1);
        if(!file.exists()) {
            System.out.println("未找到目标文件。");//指定路径下的文件不存在则输出:未找到目标文件
        }else {
            try {
                BufferedReader br = new BufferedReader(new FileReader(file));//用bufferedreader可以一次读一行
                while ((t = br.readLine())!= null) {
                    if(t.trim().startsWith("//") == true || t.trim().startsWith("/*")==true ||t.trim().startsWith("}/*")==true || t.trim().startsWith("}//")==true){
                        zl=zl+1;
                    }// 计算注释行数,去掉string首尾空格数
                    else if(t.trim().length()==0 || (t.trim().startsWith("}") == true && t.trim().length()==1)) {
                        kl=kl+1;
                    }// 计算注空行数,去掉string首尾空格数
                    else {
                        dl=dl+1;
                    }// 剩下的便是代码行
                }br.close();

            System.out.println("该文件的空行数:"+kl);//输出
            System.out.println("该文件注释行数"+zl);
            System.out.println("该文件代码行数"+dl);
        }catch (IOException ex) {
            ex.printStackTrace();
            }
       }
    }
  • 拓展功能-a。

             一开始以为可以一次读一行,一行中又可以一个字符一个字符地计算,后面报错发现只能用一个String类,然后查书发现String超好用,可以自动把首位空格忽略掉,还可以用以什么开头来判断这一行属于什么行,ok。

public static void file(String filess) {
        File file = new File (filess);
        String[] files = file.list();//列出File对象的所有子文件名和路径名,返回String数组
        for(String f : files) {
            System.out.println("文件"+f+"的数据信息如下:");
            getchars(filess+"/"+f);
            getwords(filess+"/"+f);
            getlines(filess+"/"+f);
            getkonglines(filess+"/"+f);
        }
        
        
    }
}
  • 拓展功能-s ,这个,实在是不知道怎么实现后面的条件限制,只写出了一个处理目录下所有的文件的这么一个方法了。

 运行结果:

java代码变成sdk_java代码变成sdk

java代码变成sdk_java代码变成sdk_02

java代码变成sdk_java_03

java代码变成sdk_目标文件_04

java代码变成sdk_java_05

java代码变成sdk_java代码变成sdk_06

 

 

 

PSP

  • 实现之前先在PSP中预估时间
  • 实施后各个环节实际花费多少时间也请做记录
  • 表中有一项: Estimate 指的“预估”这个活动,“预估时间”也是一项任务。
  • 例如:我估计自己需要花30分钟来估算出整个项目需要多少时间完成,结果我花了20分钟估算出整个项目需要6个小时完成。Estimate这一项应该在“预估耗时”填写30分钟,实际耗时填写“20”分钟。
  • 一级和二级活动的包含关系:
  • Planning 这个一级活动包含了1个二级活动(Estimate)
  • Development 这个一级活动包含了8个二级活动
  • Reporting 这个一级活动包含了3个二级活动
  • 大家在记录时间的时候, 只用记录二级活动, 然后把总数加了, 就是相应的一级活动的时间

PSP2.1

Personal Software Process Stages

预估耗时

实际耗时

Planning

计划

 5min

5min 

· Estimate

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

 5min

 5min

Development

开发

 3d

3d9h 

· Analysis

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

 5h

5h 

· Design Spec

· 生成设计文档

 30min


· Design Review

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

 0


· Coding Standard

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

 0


· Design

· 具体设计

 5h

 3h

· Coding

· 具体编码

2d 

 3d

· Code Review

· 代码复审

30min 

30min 

· Test

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

2h 

30min 

Reporting

报告

 70min

70min 

· Test Report

· 测试报告



· Size Measurement

· 计算工作量

10min 

 10min

· Postmortem & Process Improvement Plan

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

 1h

1h 

 

合计

 3d75min                              

 

 实际耗时

 3d10h15min

 上面那个表格我不清楚该怎么弄。。实际耗时就加在那下面吧

 

记录自己的学习进度条(每周追加)

第N周

新增代码(行)

累计代码(行)

本周学习耗时(小时)

累计学习耗时(小时)

重要成长

1

200

200

2d

2d

重新熟悉了java语言

---恢复内容结束---