wordcount

1.GitHub项目地址:https://github.com/qtqint/wordcount

2.题目描述
1. 实现一个简单而完整的软件工具(源程序特征统计程序)。
2. 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
3. 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
3.项目要求

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

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

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

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

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

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

高级功能:

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

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


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

  1. 已实现功能:

基本功能:-c,-w,-l

扩展功能:-s,-a

  1. PSP

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30

20 

· Estimate

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

 12*60

 15*60

Development

开发

 8*60

11*60 

· Analysis

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

 4*60

 4*60

· Design Spec

· 生成设计文档

 

 

· Design Review

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

 

 

· Coding Standard

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

 

 

· Design

· 具体设计

30

 30

· Coding

· 具体编码

 6.5*60

 9.5*60

· Code Review

· 代码复审

 15

15 

· Test

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

 1*60

 3*60

Reporting

报告

 

 

· Test Report

· 测试报告

 30

 30

· Size Measurement

· 计算工作量

 10

 15

· Postmortem & Process Improvement Plan

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

 10

 20

合计

 

12*60

15*60

  1. 设计思路:

先根据需求写好窗体并添加按钮,再依次实现功能。

  1. 代码实现:

1class

public class mainframe extends JFrame{

private JTextField textField;

private JPanel panel = new JPanel();

private JFileChooser fileChooser = new JFileChooser();

String selectedFile;

//主窗体设置

public mainframe() {

setTitle("wc.exe");

setBounds(400, 400, 600, 150);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JLabel label = new JLabel();

label.setText("文件:");

panel.add(label);

textField = new JTextField();

textField.setColumns(20);

panel.add(textField);

 

JButton button = new JButton("选择文件");

JButton _char = new JButton("-c"); //返回文件 file.c 的字符数

JButton _word = new JButton("-w"); //返回文件 file.c 的词的数目

JButton _line = new JButton("-l"); //返回文件 file.c 的行数

JButton _other = new JButton("-a");  //返回更复杂的数据(代码行 / 空行 / 注释行)

 

_char.setMargin(new Insets(0,20,10,20));

_word.setMargin(new Insets(0,10,10,20));

_line.setMargin(new Insets(0,10,10,20));

_other.setMargin(new Insets(0,10,10,20));

 

 

JLabel labelin = new JLabel("递归遍历文件夹(-s)");

JTextField textField1 = new JTextField(16);

JButton inbutton = new JButton("确定");

Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());

contentPane.add(labelin);

contentPane.add(textField1);

contentPane.add(inbutton);

 

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int i = fileChooser.showOpenDialog(getContentPane());// 显示文件选择对话框

if (i == JFileChooser.APPROVE_OPTION) {

selectedFile = fileChooser.getSelectedFile().getAbsolutePath();// 获得选中的文件对象

String[] filehouzhui = selectedFile.split("\\.");

int Index = filehouzhui.length -1;

        System.out.println(filehouzhui[Index]);

System.out.println(filehouzhui);

textField.setText(selectedFile);// 显示选中文件的名称

}

}

});

panel.add(button);

panel.add(_char);

panel.add(_word);

panel.add(_line);

panel.add(_other);

 

add(panel, BorderLayout.NORTH);

setVisible(true);

 

_char.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int num = c(selectedFile); //返回文件 file.c 的字符数

JOptionPane.showMessageDialog(null, selectedFile+"字符数为"+num);

}

});

_word.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int num = w(selectedFile); //返回文件 file.c 的词的数目

JOptionPane.showMessageDialog(null, selectedFile+"的词数为"+num);

}

});

_line.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int num = l(selectedFile); //返回文件 file.c 的行数

JOptionPane.showMessageDialog(null, selectedFile+"的行数为"+num);

}

});

_other.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int n1 = o(selectedFile,1); //空行

int n2 = o(selectedFile,2); //代码行

int n3 = o(selectedFile,3); //注释行

JOptionPane.showMessageDialog(null, selectedFile+"的空行数为"+n1+'\n'+selectedFile+"代码行数为"+n2+'\n'+selectedFile+"注释行数为"+n3);

}

});

inbutton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

String str = textField1.getText();

listFile(str); //递归遍历文件夹内所有文件

}

});

}

(2) 递归遍历文件夹功能

public static void listFile(String path)  

    {  

File dir = new File(path);

        File[] files=dir.listFiles();   //列出所有子文件  

        for(File file :files)  

        {  

            if(file.isFile())//是文件则输出文件名字  

            {  

             due(path+"\\"+file.getName());

                System.out.println(path+"\\"+file.getName());  

            }else if(file.isDirectory())//是文件夹则输出文件夹的名字,并递归遍历  

            {   

                System.out.println(path+file.getName());

                listFile(path);

            }  

        }  

}

3)对文件夹内所有文件进行处理

public static void due(String file) { //-s   递归处理目录下符合条件的文件

int n1 = c(file);

int n2 = w(file);

int n3 = l(file);

int n4 = o(file,1);

int n5 = o(file,2);

int n6 = o(file,3);

JOptionPane.showMessageDialog(null, file+"的字符数为"+n1+"\n"+file+"的单词数为"+n2+"\n"+file+"的行数为"

+n3+"\n"+file+"的空行数为"+n4+"\n"+file+"的代码行数为"+n5+"\n"+file+"的注释行数为"+n6);

}

(4-o功能的实现

public static int o(String file,int t) { //-a,t=1返回代码行 t=2返回空行 t=3返回注释行

int konghang = 0;

int daimahang = 0;

int zhushihang = 0;

int j = 0; //j是标记

String temp = null;

BufferedReader br = null;

try {

br = new BufferedReader(new FileReader(file));

    while ((temp = br.readLine()) != null) {

     temp = temp.replaceAll("\\{","").replaceAll("\\}","");

     if(j==0) {

         if((temp.trim().indexOf("/*")==0)) {zhushihang++;j=1;}

         else if((temp.trim().indexOf("//")==0)) zhushihang++;

         else if(temp.trim().length()>0) daimahang++;

         else konghang++;

     }

     else{

     zhushihang++;

         if(temp.contains("*/")) j=0;         

        }

     }

     //br.close();

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            br.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

if(t==1) return konghang;

else if(t==2) return daimahang;

else return zhushihang;

}

(5)-l功能的实现

public static int l(String file) { //返回文件 file.c 的行数

int linenum = 0;

    BufferedReader br = null;

    try {

    br = new BufferedReader(new FileReader(file));

    String temp = null;

    while (((temp = br.readLine()) != null)) {

         linenum++;

     }

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            br.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    return linenum;

}

(6-w功能的实现

public static int w(String file) {  //返回文件 file.c 的词的数目

int wordnum = 0;int i,j=0; //j是标记

BufferedReader br = null;

    try {

    br = new BufferedReader(new FileReader(file));

    String temp = "";

    while ((temp = br.readLine()) != null) {

        char[] des = temp.trim().toCharArray();

        for (i=0;i<des.length;i++) {

         if (j==0&((des[i]>=48&des[i]<=57)|(des[i]>=65&des[i]<=90)|(des[i]>=97&des[i]<=122))) {wordnum++;j=1;}

         if(des[i]<48|(des[i]>57&des[i]<65)|(des[i]>90&des[i]<97)|des[i]>122) j=0;

        }}

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            br.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    return wordnum;

}

7-c功能的实现

public static int c(String file) {  //返回文件 file.c 的字符数

int charnum = 0;int i;

    BufferedReader br = null;

    try {

    br = new BufferedReader(new FileReader(file));

    String temp = "";

    while ((temp = br.readLine()) != null) {

        char[] des = temp.trim().toCharArray();

        for (i=0;i<des.length;i++)  

         if (des[i]!=' '&des[i]!='\t') charnum++;

        }

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            br.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    return charnum;

}

(8)主函数

public static void main(String[] args) {

mainframe test = new mainframe();

}

  1. 代码测试
  2. 对单个文件进行测试-c,-w,-l,-a

 

 

 

  1. 测试功能-s

 

 

8.项目总结

  这次作业进一步锻炼我JAVA的编程能力,项目中的规范仍然不够,且仍然存在bug,例如:对文件夹的递归遍历处理得还不够好,以及还未解决注释算入字符数的问题,总体来说还不够熟练,很多知识都要上网查,做作业的时候遇到的问题有很多,花了很多的时间解决问题。利用PSP也提高了我的规划能力,提高我的效率。对于JAVA还要学习东西很多,我还必须进一步地提高自我,不断学习

posted @ 2020-03-15 13:25  qintc  阅读(94)  评论(0)    收藏  举报