WordCount

github地址:https://github.com/szc1506/WChtml

一.PSP表格java

PSP2.1git

PSP階段程序員

預估耗時github

(分鐘)數組

實際耗時intellij-idea

(分鐘)app

Planningide

計劃函數

 15  25

· Estimate

· 估計這個任務須要多少時間

 30  30

Development

開發

 280  350

· Analysis

· 需求分析 (包括學習新技術)

 100  120

· Design Spec

· 生成設計文檔

 50  60

· Design Review

· 設計複審 (和同事審覈設計文檔)

 30  20

· Coding Standard

· 代碼規範 (爲目前的開發制定合適的規範)

 20  30

· Design

· 具體設計

110 80

· Coding

· 具體編碼

 300  450

· Code Review

· 代碼複審

 60  60

· Test

· 測試(自我測試,修改代碼,提交修改)

 200  180

Reporting

報告

 150  220

· Test Report

· 測試報告

 120  150

· Size Measurement

· 計算工做量

 30  25

· Postmortem & Process Improvement Plan

· 過後總結, 並提出過程改進計劃

 60  45
 

合計

 1555  1845

二.需求說明

WordCount的需求能夠歸納爲:對程序設計語言源文件統計字符數、單詞數、行數,統計結果以指定格式輸出到默認文件中,以及其餘擴展功能,並可以快速地處理多個文件。

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

wc.exe -s            //遞歸處理目錄下符合條件的文件

wc.exe -a file.c   //返回更復雜的數據(代碼行 / 空行 / 註釋行)

wc.exe -e stopList.txt  // 停用詞表,統計文件單詞總數時,不統計該表中的單

三.程序實現過程

   第一次拿到題目時限定語言是java,由於自己對java不是很熟悉,就花了較多的時間在熟悉java和配環境上。參考連接:http://www.runoob.com/java/java-environment-setup.html。題目描述要求統計文件中的字符數,先讀入文件,而後字符數,單詞數,行數這三個能夠一塊兒統計,由於能夠一次讀一行。擴展功能中的各類代碼行,註釋行能夠用正則式來匹配,遞歸處理文件夾下文件能夠寫一個遞歸函數,停用詞表能夠先讀出全部停用詞,放到數組裏,而後匹配全部單詞,匹配則不用加一。找資料的過程大概就是JAVA的各類使用方法,文末已經給出連接。

四.代碼說明

1.字符計數:每讀入一個字符,判斷是否是回車換行符,不是則字符計數器加一

package java86;
import java.io.*;
import java.util.*;
public class Javatest {
    public static int countC(String fn) {//統計字符數
        BufferedReader reader = null;
        int res = 0;
        try {
            reader = new BufferedReader(new FileReader(fn));
            String str = null;
            while ((str = reader.readLine()) != null) {
                res += str.length();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

2.單詞統計:按字符流讀取文件,對每個字符作判斷,若是不是換行符或空格則繼續往下讀取;當讀取到換行符或者空格是,將前面讀到的字符拼做一個單詞,單詞計數加一

public static int countW(String fn, List<String> list) {//統計單詞數目
        BufferedReader reader = null;
        int res = 0;
        try {
            reader = new BufferedReader(new FileReader(fn));
            String str = null;
            while ((str = reader.readLine()) != null) {
                String[] temp = str.split(" |,");
                for (String s : temp) {
                    if (s != null && !list.contains(s)) {
                        ++res;
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

3.行數讀取調用java API,統計計數

public static int countL(String fn) {//統計行數
        BufferedReader reader = null;
        int res = 0;
        try {
            reader = new BufferedReader(new FileReader(fn));
            String str = null;
            while ((str = reader.readLine()) != null) {
                ++res;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

4.擴展功能

遞歸獲取文件:獲取文件目錄,判斷是否是目錄,若是是目錄則遞歸獲取該目錄下的內容;若是符合要求的文件,則先將文件名存儲,與以後的執行一同進行

代碼行,註釋行,空行的統計。

對於單詞數、字符數、行數的統計:

package text1;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Pattern;
public class extendedFun {
    //遞歸處理該目錄下的同類型文件
    static void allfile(String[] list){
        int lenth=list.length;
        String myfile=null;
        myfile=list[lenth-1];
        if(lenth==8)
              myfile=list[3];    
        File directory = new File("");//參數爲空
        String courseFile;
        try {
            courseFile = directory.getCanonicalPath();//獲取當前目錄路徑
             // 得到指定文件對象  
            File file = new File(courseFile);   
            // 得到該文件夾內的全部文件   
            File[] array = file.listFiles();   
            File afile=new File(myfile); 
            String fileName=afile.getName();    
            String fileTyle=fileName.substring(fileName.lastIndexOf("."),fileName.length()); //獲取文件類型
            for(int i=0;i<array.length;i++)
            {   
                if(array[i].isFile())//若是是文件
                {   
                    if(array[i].getName().endsWith(fileTyle)){
                        if(lenth==2){
                        if(list[0].equals("-l")||list[0].equals("-c")||list[0].equals("-w"))
                                basecount.count(list[0],array[i].getName());
                        else if(list[0].equals("-a")){
                            moredata(array[i].getName(),null);
                        }
                        }
                        else if(lenth==3&&(list[0].equals("-l")||list[0].equals("-c")||list[0].equals("-w"))&&(list[1].equals("-l")||list[1].equals("-c")||list[1].equals("-w"))){
                            basecount.count(list[0],list[1],array[i].getName());
                        }
                        else if(lenth==4){
                            basecount.count(list[0],list[1],list[2],array[i].getName());
                        }
                        else if(lenth==8)
                        {
                            if(list[0].equals("-a")){
                            basecount.count(list[1], array[i].getName(),list[7]);
                            basecount.count(list[2], array[i].getName(),list[7]);
                            moredata(array[i].getName(),list[7]);
                            stopcount(array[i].getName(),list[5],list[7]);
                            }                  
                        }
                        else System.out.println("輸入格式錯誤");
                    }
                }
            }   
        } catch (IOException e) {
            e.printStackTrace();
        }    
    }
    //統計代碼行/空行/註釋行
    static void moredata(String myfile,String outfile)throws FileNotFoundException {  
        if(outfile==null)
            outfile="result.txt";
        String sfile=new String(myfile);
         File file=new File(sfile);
         // 記錄註釋行數  
         long annotationLine = 0;  
        // 記錄空白行數  
        long blankLine = 0;  
        // 記錄有效代碼的行數  
        long codeLine = 0;   
        //假註釋
        long notLine=0;
        if (file == null || !file.exists())   
            throw new FileNotFoundException(file + ",文件不存在!"); 
        BufferedReader br = null;  
        // 判斷此行是否爲註釋行  
        boolean comment = false;  
        int whiteLines = 0;  
        int commentLines = 0;  
        int normalLines = 0;       
        try {  
            br = new BufferedReader(new FileReader(file));  
            String line = "";  
            while ((line = br.readLine()) != null) {  
                line = line.trim();  
                if (line.matches("^[//s&&[^//n]]*$")||line.equals("{")||line.equals("}")) {  
                    // 空行 :本行所有是空格或格式控制字符,若是包括代碼,則只有不超過一個可顯示的字符,例如「{」
                    whiteLines++;      
                } 
               /* 本行不是代碼行,而且本行包括註釋。一個有趣的例子是有些程序員會在單字符後面加註釋:
                *  }//註釋
                */
                else if (line.startsWith("/*") && !line.endsWith("*/")||((line.startsWith("{/*")||line.startsWith("}/*"))&&!line.endsWith("*/"))){
                    // 判斷此行爲"/*"開頭的註釋行  
                    commentLines++;  
                    comment = true;  
                } else if (comment == true && !line.endsWith("*/")&&!line.startsWith("*/")) {  
                    // 爲多行註釋中的一行(不是開頭和結尾)
                    notLine++;
                    commentLines++;  
                } else if (comment == true && (line.endsWith("*/")||line.startsWith("*/"))) {  
                    // 爲多行註釋的結束行  
                    commentLines++;  
                    comment = false;  
                } else if (line.startsWith("//")|| line.startsWith("}//")||line.startsWith("{//")||
                            ((line.startsWith("{/*") ||line.startsWith("}/*")||line.startsWith("/*")) && line.endsWith("*/"))) {  
                    // 單行註釋行  
                    commentLines++;  
                } else {  
                    // 正常代碼行  
                    //System.out.println(line);
                    normalLines++;  
                }  
            }        
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            if (br != null) {  
                try {  
                    br.close();  
                    br = null;  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
            try{
                 //打開一個寫文件器,構造函數中的第二個參數true表示以追加形式寫文件
                FileWriter writer = new FileWriter(outfile, true);
                char[] message=(myfile+",代碼行/空行/註釋行:"+(normalLines+notLine)+"/"+whiteLines+"/"+(commentLines-notLine)+"\r\n").toCharArray();//換行"\r\n"不是"\n"
                writer.write(message);
                 writer.close();
             }
             catch(IOException e){
                 System.out.println("File read/write Error"+e);
             }
        }  
    } 
    //調用停用詞表,重寫統計單詞數
    static void stopcount(String thefile,String txt,String output){
        int stopcount=0;
        int wordcount=0;
        File stopfile=new File(txt);
         File file=new File(thefile);
        ArrayList<String> stop=new ArrayList<String>(3);
        
//       讀入stopfile.txt的單詞到一個動態string數組中保存    
         if(stopfile.exists()){
             try{
                 FileInputStream fis=new FileInputStream(stopfile);
                 InputStreamReader isr=new InputStreamReader(fis,"UTF-8");
                 BufferedReader br=new BufferedReader(isr);
                 String line=new String("");
                 StringBuffer sb=new StringBuffer();
                  TreeMap<String, Integer> map = new TreeMap<>(); 
                 String[] split =null;
                 while((line=br.readLine())!=null){
                      sb.append(line);
                     split = line.split("\\s+");  
                    for (int i = 0; i < split.length; i++) {  
//                        獲取到每個單詞  
                          Integer integer = map.get(split[i]);  
//                        若是這個單詞在map中沒有,賦值1  
                          if(null==integer){  
                              map.put(split[i], 1);  
                          }
                      }  
                 }         
                 Set<String> keySet = map.keySet();  
                  for (String string : keySet) {  
                      stop.add(string);    
                  }
                 br.close();
                 isr.close();
                 fis.close();
             }
             catch(FileNotFoundException e){
                 e.printStackTrace();
             }
             catch(UnsupportedEncodingException e){
                 e.printStackTrace();
             }
             catch(IOException e){
                 e.printStackTrace();
             }
             
         }

         //統計stop表的總數目
         if(file.exists()){
             try{
                 FileInputStream fis=new FileInputStream(file);
                 InputStreamReader isr=new InputStreamReader(fis,"UTF-8");
                 BufferedReader br=new BufferedReader(isr);
                 String line=new String("");
                 StringBuffer sb=new StringBuffer();
                  TreeMap<String, Integer> map = new TreeMap<>(); 
                 while((line=br.readLine())!=null){
                     String[] split = line.split("\\s++|\\.|,|\\;|\\(|\\)|\\[|\\]|\\<|\\>|\\=|\\-|\\+|\\*|\\/|\\{|\\}");  //去除多個空格\\s+
                     for (int i = 0; i < split.length; i++) {                     
//                       獲取到每個單詞  
                         Integer integer = map.get(split[i]);  
//                       若是這個單詞在map中沒有,賦值1  
                         if(null==integer){  
                             map.put(split[i], 1);  
                         }else{  
//                           若是有,在原來的個數上加上一  
                             map.put(split[i], ++integer);  
                         }  
                     }  
                 }
//               遍歷,根據key獲取所對應的value  
                 Set<String> keySet = map.keySet();  
                 for (String string : keySet) { 
                     int i=0;
                     if(!(string.equals(""))){
                     wordcount+=map.get(string);
                 while(i<stop.size()){
                        if(string.equalsIgnoreCase(stop.get(i++)))//不區分大小寫判斷
                    { 
                             stopcount+=map.get(string);
                             //System.out.println(string+":"+map.get(string));  
                        }}
                        
               }
                 } 
                 //System.out.println(wordcount+"  "+stopcount+"  "+(wordcount-stopcount));
                 sb.append(line);
                 br.close();
                 isr.close();
                 fis.close();
                 
             }
             catch(FileNotFoundException e){
                 e.printStackTrace();
             }
             catch(UnsupportedEncodingException e){
                 e.printStackTrace();
             }
             catch(IOException e){
                 e.printStackTrace();
             }
         }
         try{
            //打開一個寫文件器,構造函數中的第二個參數true表示以追加形式寫文件
             if(output==null)
                 output="output.txt";
            FileWriter writer = new FileWriter(output, true);
            char[] message=(thefile+", 單詞數(停用後):"+(wordcount-stopcount)+"\r\n").toCharArray();//換行"\r\n"不是"\n"
            writer.write(message);
             writer.close();
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }
} 

五.測試過程

測試過程對於每一項功能單獨測試,再進行組合測試,確保覆蓋了全部可執行的代碼,對文件名輸入文件和文件夾也做出了測試,總共設計10個測試用例:

(1)wc.exe -l ../test/test.c -o out1.txt                                (2)wc.exe -w ../test/test.c -o out2.txt

(3)wc.exe -a ../test/test.c -o out3.txt                               (4)wc.exe -c ../test/test.c -o out4.txt

(5)wc.exe -l -w -a -c ../test/test.c -o out5.txt                   (6)wc.exe -a ../test/ -o out6.txt

(7)wc.exe -a -s ../test/ -o out7.txt                                    (8)wc.exe -a ../test/*.c -o out8.txt

(9)wc.exe -a ../test/*.c -e ../stop.txt -o out9.txt                (10)wc.exe -l -w -a -c -s ../test/ -e ../stop.txt -o out10.tx

六.總結 

   軟件測試工做是一個系統而複雜的工程,軟件測試的目的就是確保軟件的質量、確認軟件以正確的方式作了你所指望的事情,因此工做的主要任務是發現軟件的錯誤、有效定義和實現軟件成分由底層到高層的組裝過程、驗證軟件是否知足規格書要求和系統定義文檔所規定的技術要求、爲軟件質量模型的創建提供依據。
    並且軟件的測試不只是要確保軟件的質量,還要給開發人員提供信息,以方便其爲風險評估作相應的準備,以及爲其提供分析依據,重要的是要貫穿在整個軟件開發的過程當中,保證整個  軟件開發的過程是高質量的。 軟件測試對測試工程師來說,要求具有較強的專業知識,嚴謹細心耐心的測試態度,良好的反向思惟、發散思惟能力、溝通能力等等。

部分代碼參考1504班成建偉

六.參考連接

1. http://www.cnblogs.com/winterfells/p/7965596.html

2. http://www.runoob.com/java/java-environment-setup.html

3.https://stackoverflow.com/questions/25555717/intellij-idea-javafx-artifact-build-does-not-generate-exe

4. http://blog.csdn.net/daxiang_zhang/article/details/2149896

5. http://blog.csdn.net/hpchenqi_16/article/details/48504111

6. http://blog.csdn.net/alex__0805/article/details/50895222

7.https://bbs.csdn.net/topics/390567815

相關文章
相關標籤/搜索