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.设计思路:

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

2.代码实现:

  1 import java.awt.*;
  2 import java.awt.event.*;
  3 import java.io.*;
  4 import javax.swing.*;
  5  
  6 public class mainframe extends JFrame{
  7     private JTextField textField;
  8     private JPanel panel = new JPanel();
  9     private JFileChooser fileChooser = new JFileChooser();        
 10     String selectedFile;
 11     //主窗体设置
 12     public mainframe() {
 13         setTitle("wc.exe");
 14         setBounds(400, 400, 600, 150);
 15         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
 16         final JLabel label = new JLabel();
 17         label.setText("文件:");
 18         panel.add(label);
 19         textField = new JTextField();
 20         textField.setColumns(20);
 21         panel.add(textField);
 22 
 23         JButton button = new JButton("选择文件");
 24         JButton _char = new JButton("-c");    //返回文件 file.c 的字符数
 25         JButton _word = new JButton("-w");    //返回文件 file.c 的词的数目
 26         JButton _line = new JButton("-l");    //返回文件 file.c 的行数
 27         JButton _other = new JButton("-a");     //返回更复杂的数据(代码行 / 空行 / 注释行)
 28         
 29         _char.setMargin(new Insets(0,20,10,20));
 30         _word.setMargin(new Insets(0,10,10,20));
 31         _line.setMargin(new Insets(0,10,10,20));
 32         _other.setMargin(new Insets(0,10,10,20));
 33     
 34         
 35         JLabel labelin = new JLabel("递归遍历文件夹(-s)");
 36         JTextField textField1 = new JTextField(16);
 37         JButton inbutton = new JButton("确定");
 38         Container contentPane = getContentPane();
 39         contentPane.setLayout(new FlowLayout());
 40         contentPane.add(labelin);
 41         contentPane.add(textField1);
 42         contentPane.add(inbutton);
 43         
 44         button.addActionListener(new ActionListener() {            
 45             public void actionPerformed(ActionEvent e) {                
 46                 int i = fileChooser.showOpenDialog(getContentPane());// 显示文件选择对话框    
 47                 if (i == JFileChooser.APPROVE_OPTION) {                
 48                     selectedFile = fileChooser.getSelectedFile().getAbsolutePath();// 获得选中的文件对象
 49                     String[] filehouzhui = selectedFile.split("\\.");
 50                     int Index = filehouzhui.length -1;
 51                     System.out.println(filehouzhui[Index]);
 52                     System.out.println(filehouzhui);
 53                     textField.setText(selectedFile);// 显示选中文件的名称                    
 54                 }
 55             }
 56         });
 57         panel.add(button);
 58         panel.add(_char);
 59         panel.add(_word);
 60         panel.add(_line);
 61         panel.add(_other);
 62         
 63         add(panel, BorderLayout.NORTH);
 64         setVisible(true);
 65         
 66         _char.addActionListener(new ActionListener() {    
 67             public void actionPerformed(ActionEvent e) {
 68                 int num = c(selectedFile);    //返回文件 file.c 的字符数
 69                 JOptionPane.showMessageDialog(null, selectedFile+"字符数为"+num);
 70             }
 71         });
 72         _word.addActionListener(new ActionListener() {
 73             public void actionPerformed(ActionEvent e) {
 74                 int num = w(selectedFile);    //返回文件 file.c 的词的数目
 75                 JOptionPane.showMessageDialog(null, selectedFile+"的词数为"+num);
 76             }
 77         });
 78         _line.addActionListener(new ActionListener() {
 79             public void actionPerformed(ActionEvent e) {
 80                 int num = l(selectedFile);    //返回文件 file.c 的行数
 81                 JOptionPane.showMessageDialog(null, selectedFile+"的行数为"+num);
 82             }
 83         });
 84         _other.addActionListener(new ActionListener() {
 85             public void actionPerformed(ActionEvent e) {
 86                 int n1 = o(selectedFile,1);    //空行
 87                 int n2 = o(selectedFile,2);    //代码行
 88                 int n3 = o(selectedFile,3);    //注释行
 89                 JOptionPane.showMessageDialog(null, selectedFile+"的空行数为"+n1+'\n'+selectedFile+"代码行数为"+n2+'\n'+selectedFile+"注释行数为"+n3);
 90             }
 91         });        
 92         inbutton.addActionListener(new ActionListener() {
 93             public void actionPerformed(ActionEvent e) {
 94                 String str = textField1.getText();
 95                 listFile(str);            //递归遍历文件夹内所有文件    
 96             }
 97         });
 98     }
 99     
100 
101     public static void listFile(String path)  
102     {  
103         File dir = new File(path);
104         File[] files=dir.listFiles();   //列出所有子文件  
105         for(File file :files)  
106         {  
107             if(file.isFile())//是文件则输出文件名字  
108             {  
109                 due(path+"\\"+file.getName());
110                 System.out.println(path+"\\"+file.getName());  
111             }else if(file.isDirectory())//是文件夹则输出文件夹的名字,并递归遍历  
112             {   
113                 System.out.println(path+file.getName()); 
114                 listFile(path);
115             }  
116         }  
117     }
118     public static void due(String file) {    //-s   递归处理目录下符合条件的文件
119         int n1 = c(file);
120         int n2 = w(file);
121         int n3 = l(file);
122         int n4 = o(file,1);
123         int n5 = o(file,2);
124         int n6 = o(file,3);
125         JOptionPane.showMessageDialog(null, file+"的字符数为"+n1+"\n"+file+"的单词数为"+n2+"\n"+file+"的行数为"
126         +n3+"\n"+file+"的空行数为"+n4+"\n"+file+"的代码行数为"+n5+"\n"+file+"的注释行数为"+n6);
127     }
128     public static int o(String file,int t) {    //-a,t=1返回代码行 t=2返回空行 t=3返回注释行
129         int konghang = 0;
130         int daimahang = 0;
131         int zhushihang = 0;
132         int j = 0;    //j是标记
133         String temp = null;
134         BufferedReader br = null;
135         try {
136             br = new BufferedReader(new FileReader(file));
137             while ((temp = br.readLine()) != null) {
138                 temp = temp.replaceAll("\\{","").replaceAll("\\}","");
139                 if(j==0) {
140                     if((temp.trim().indexOf("/*")==0))    {zhushihang++;j=1;}
141                     else if((temp.trim().indexOf("//")==0))    zhushihang++;
142                     else if(temp.trim().length()>0)    daimahang++;
143                     else konghang++;
144                 }
145                 else{
146                     zhushihang++;
147                     if(temp.contains("*/"))     j=0;                    
148                 }
149                 }
150                 //br.close();
151             } catch (FileNotFoundException e) {
152                 e.printStackTrace();
153             } catch (IOException e) {
154                 e.printStackTrace();
155             } finally {
156                 try {
157                     br.close();
158                 } catch (IOException e) {
159                     e.printStackTrace();
160                 }
161             }
162             if(t==1)    return konghang;
163             else if(t==2)    return daimahang;
164             else    return zhushihang;
165     }
166     public static int l(String file) {    //返回文件 file.c 的行数
167         int linenum = 0;
168         BufferedReader br = null;
169         try {
170         br = new BufferedReader(new FileReader(file));
171         String temp = null;
172         while (((temp = br.readLine()) != null)) {
173                 linenum++;
174             }
175         } catch (FileNotFoundException e) {
176             e.printStackTrace();
177         } catch (IOException e) {
178             e.printStackTrace();
179         } finally {
180             try {
181                 br.close();
182             } catch (IOException e) {
183                 e.printStackTrace();
184             }
185         }
186         return linenum;
187     }
188     public static int w(String file) {     //返回文件 file.c 的词的数目
189         int wordnum = 0;int i,j=0;    //j是标记
190         BufferedReader br = null;
191         try {
192         br = new BufferedReader(new FileReader(file));
193         String temp = "";
194         while ((temp = br.readLine()) != null) {
195             char[] des = temp.trim().toCharArray();
196             for (i=0;i) {
197                 if (j==0&((des[i]>=48&des[i]<=57)|(des[i]>=65&des[i]<=90)|(des[i]>=97&des[i]<=122)))    {wordnum++;j=1;}
198                 if(des[i]<48|(des[i]>57&des[i]<65)|(des[i]>90&des[i]<97)|des[i]>122)    j=0;
199             }}
200         } catch (FileNotFoundException e) {
201             e.printStackTrace();
202         } catch (IOException e) {
203             e.printStackTrace();
204         } finally {
205             try {
206                 br.close();
207             } catch (IOException e) {
208                 e.printStackTrace();
209             }
210         }
211         return wordnum;
212     }
213     public static int c(String file) {     //返回文件 file.c 的字符数
214         int charnum = 0;int i;    
215         BufferedReader br = null;
216         try {
217         br = new BufferedReader(new FileReader(file));
218         String temp = "";
219         while ((temp = br.readLine()) != null) {
220             char[] des = temp.trim().toCharArray();
221             for (i=0;i)     
222                 if (des[i]!=' '&des[i]!='\t')    charnum++;
223             }
224         } catch (FileNotFoundException e) {
225             e.printStackTrace();
226         } catch (IOException e) {
227             e.printStackTrace();
228         } finally {
229             try {
230                 br.close();
231             } catch (IOException e) {
232                 e.printStackTrace();
233             }
234         }
235         return charnum;
236     }
237 
238     public static void main(String[] args) {
239         mainframe test = new mainframe();
240     }
241 }

 

3.代码测试

对单个文件进行测试-c,-w,-l,-a

WordCount_第1张图片WordCount_第2张图片WordCount_第3张图片

测试功能-s

WordCount_第4张图片WordCount_第5张图片WordCount_第6张图片WordCount_第7张图片WordCount_第8张图片WordCount_第9张图片

4.项目总结

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

5.参考资料

java做一个简单的文本输入框https://www.pianshen.com/article/2855335832/

java文件夹递归遍历https://www.cnblogs.com/invban/p/7975529.html

java文件选择https://blog.csdn.net/qq_36761831/article/details/81489699

你可能感兴趣的:(WordCount)