軟件質量與測試第二周作業 WordCount
第二周作業 WordCount
一、Github 地址
https://github.com/llag9810/Software-Quality-and-Testing-Wordcount
二、PSP2.1 表格
PSP2.1 |
PSP階段 |
預估耗時 (分鐘) |
實際耗時 (分鐘) |
Planning |
計劃 |
60 |
25 |
· Estimate |
· 估計這個任務需要多少時間 |
30 |
15 |
Development |
開發 |
600 |
810 |
· Analysis |
· 需求分析 (包括學習新技術) |
60 |
60 |
· Design Spec |
· 生成設計文檔 |
30 |
30 |
· Design Review |
· 設計復審 (和同事審核設計文檔) |
0 |
0 |
· Coding Standard |
· 代碼規範 (為目前的開發制定合適的規範) |
20 |
20 |
· Design |
· 具體設計 |
20 |
40 |
· Coding |
· 具體編碼 |
250 |
350 |
· Code Review |
· 代碼復審 |
40 |
40 |
· Test |
· 測試(自我測試,修改代碼,提交修改) |
60 |
100 |
Reporting |
報告 |
60 |
85 |
· Test Report |
· 測試報告 |
40 |
60 |
· Size Measurement |
· 計算工作量 |
10 |
5 |
· Postmortem & Process Improvement Plan |
· 事後總結, 並提出過程改進計劃 |
10 |
20 |
|
合計 |
660 |
835 |
三、解題思路
1. 解析參數。Java 語言的參數在 main 方法裏為一個 args 數組,根據這個數組來解析參數。其中包括兩個方面,一是判斷參數輸入的合法性,二是解析參數的作用(即需要哪些功能)。
2. 針對文件讀寫設計函數。使用 JAVA 中的輸入、輸出流進行封裝,完成文件的讀取和結果的寫入操作。
3. 實現單詞、字符、行數的讀寫。其中,行數的讀取比較簡單,每讀一行就加1。字符的讀取同理。單詞的讀取可以使用 java 中的 Scanner,用正則表達式將分界符(delimiter)設置成空格、逗號、tab和換行,這樣每次讀一個word即可。
4. 實現stoplist:將stoplist文件裏面的內容讀到一個 HashSet 中,每次判斷讀到的單詞在不在 HashSet 中,如果在則單詞不算。
5. 實現註釋、代碼行、空行判斷:使用正則表達式按行判斷即可。
四、代碼說明
我的代碼包含兩個文件,Main.java 包含主函數和參數解析、文件打開關閉部分,Counter.java 實現了計數功能。
我這裏貼出核心部分,即計數部分的源代碼。代碼內容參見註釋:
1 /** 2 * Count the number of chars in the input stream. 3 * @param is the InputStream to count. 4 * @param ps the PrintStream to write the result. 5 */ 6 public void countChar(InputStream is, PrintStream ps) { 7 try { 8 int count = is.available(); 9 String note = ", " + "字符數: "; 10 ps.println(fileName + note + count); 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 } 15 16 17 /** 18 * Count the number of lines in the input stream. 19 * @param is the InputStream to count. 20 * @param ps the PrintStream to write the result. 21 */ 22 public void countLines(InputStream is, PrintStream ps) { 23 Scanner scanner = new Scanner(is); 24 int line = 0; 25 while (scanner.hasNextLine()) { 26 line++; 27 scanner.nextLine(); 28 } 29 String note = ", " + "行數: "; 30 ps.println(fileName + note + line); 31 } 32 33 34 /** 35 * Count words without StopList. 36 * 37 * @see #countWordsWithStopList(InputStream, PrintStream, Set) 38 */ 39 public void countWords(InputStream is, PrintStream ps) { 40 countWordsWithStopList(is, ps, null); 41 } 42 43 /** 44 * Count the number of words in the input stream. 45 * According to the requirements, the only 4 legal delimiters are: 46 * space, comma, tab and line break; 47 * 48 * @param is the InputStream to count. 49 * @param ps the PrintStream to write the result. 50 * @param stopSet A set of words that shall not be included into the count. 51 */ 52 public void countWordsWithStopList(InputStream is, PrintStream ps, Set<String> stopSet) { 53 Scanner scanner = new Scanner(is); 54 int words = 0; 55 56 Pattern pattern = Pattern.compile("\\n+|\\t+|\\s+|,"); 57 scanner.useDelimiter(pattern); 58 while (scanner.hasNext()) { 59 String word = scanner.next(); 60 if (stopSet == null || !stopSet.contains(word)) { 61 words++; 62 } 63 } 64 65 String note = ", " + "單詞數: "; 66 ps.println(fileName + note + words); 67 } 68 69 /** 70 * Count the lines of code, comment and blank. 71 */ 72 public void countCodeAndComment(InputStream is, PrintStream ps) { 73 Scanner scanner = new Scanner(is); 74 int code = 0; 75 int blank = 0; 76 int comment = 0; 77 String blankPattern = "[\\s\\t\\n]*[(){}]?"; 78 String commentPattern = "([\\s\\t]*([})]?)((/\\*|//).*))|(\\*/)"; 79 while (scanner.hasNextLine()) { 80 String line = scanner.nextLine(); 81 if (Pattern.matches(blankPattern, line)) { 82 blank++; 83 } else if (Pattern.matches(commentPattern, line)) { 84 comment++; 85 } else { 86 code++; 87 } 88 } 89 String note = ", " + "代碼行/空行/註釋行: "; 90 ps.println(fileName + note + code + "/" + blank + "/" + comment); 91 }
五、測試
我設置了如下幾個測試用例來測試不同的功能是否完全實現
1 wc.exe -a file.c 2 wc.exe -w file.c 3 wc.exe -c file.c 4 wc.exe -l file.c
5 wc.exe -w -c -l -a -s D:\test\*.c
6 wc.exe -e stop.txt -o testo.txt -a file.c
7 wc.exe -l -w -a -c -s ../test/ -e ../stop.txt -o output.txt
軟件質量與測試第二周作業 WordCount