Word Count
Word Count
一.個人Gitee地址: ofollow,noindex" target="_blank">https://gitee.com/godcoder979/ (該專案完整程式碼在這裡)
二.專案簡介:
該專案是一個統計檔案字元、單詞、行數等數目的應用程式,通過輸入命令來執行你想要的操作。所用語言:java
命令格式:
wc.exe [para] <filename> [para] <filename> ... -o <filename>
功能:
-a:統計檔案中的程式碼行、空行、註釋行;
-c:統計檔案中的字元數,不包括換行符;
-w:統計檔案中的單詞數;
-l:統計檔案的行數;
-s:統計一個資料夾中符合要求的檔案;
-o:指定輸出檔案;
三.PSP表格:
PSP2.1 | PSP階段 | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 20 | 10 |
· Estimate | · 估計這個任務需要多少時間 | 5 | 5 |
Development | 開發 | 500 | 600 |
· Analysis | · 需求分析(包括學習新技術) | 20 | 30 |
· Design Spec | · 生成設計文件 | 30 | 30 |
· Design Review | · 設計複審(和同事稽核設計文件) | 10 | 15 |
· Coding Standard | · 程式碼規範(為目前的開發制定合適的規範) | 5 | 5 |
· Design | · 具體設計 | 15 | 20 |
· Coding | · 具體編碼 | 200 | 400 |
· Code Review | · 程式碼複審 | 40 | 30 |
· Test | · 測試(自我測試,修改程式碼,提交修改) | 20 | 30 |
Reporting | 報告 | 60 | 50 |
· Test Report | · 測試報告 | 20 | 15 |
· Size Measurement | · 計算工作量 | 10 | 5 |
· Postmortem & Process improvement Plan | · 事後總結,並提出過程改進計劃 | 30 | 30 |
合計 | 580 | 660 |
四.解題思路:
整個專案比較簡單,使用者輸入需要進行的操作和基本的檔案資訊就可以儲存結果到一個檔案裡。所以可以這樣分析:
1)識別使用者輸入的選項和檔名,分析需要進行的操作
2)實現每一種功能,根據分析執行相應的操作
3)將結果儲存到一個檔案裡
程式碼模組劃分:
1)主函式:
通過使用者輸入的指令進行相應的邏輯處理
2)功能呼叫模組:
這個模組被主函式呼叫,根據分析執行相應操作
3)判斷模組:
根據使用者輸入的指令得出需要執行那些功能,這是功能呼叫模組執行的依據
4)功能實現模組:
這個模組就是實現以上統計字元、單詞等功能了
五.關鍵程式碼展示:
1.judge方法(分析使用者要實現的功能,當flag為true是代表將要實現)
1 private static void judge(String str) { 2// TODO Auto-generated method stub 3if(str.equals("-s")&&s_flag==false){ 4s_flag=true; 5} 6else if(str.equals("-*")&☆_flag==false){ 7star_flag=true; 8c_flag=true; 9w_flag=true; 10l_flag=true; 11a_flag=true; 12} 13else if(str.equals("-a")&&a_flag==false){ 14a_flag=true; 15} 16else if(str.equals("-c")&&c_flag==false){ 17c_flag=true; 18} 19else if(str.equals("-w")&&w_flag==false){ 20w_flag=true; 21} 22else if(str.equals("-l")&&l_flag==false){ 23l_flag=true; 24} 25else if(file_flag==false)//還沒有指定輸入檔案 26{ 27if(s_flag==false){//如果輸入的不是路徑 28file_name=str; 29txt_name=str; 30} 31file_flag=true; 32} 33else if(str.equals("-o")&&o_flag==false){ 34o_flag=true; 35} 36else if(o_flag==true&&file_flag==true){//已經有輸入檔案且o_flag為真但是沒有指定輸出檔案 37output_name+=str; 38all_flag=true; 39} 40else{ 41System.out.println("指令判斷完成"); 42} 43 44}
2.字元統計:
1 private static int num_of_char(String filename) { 2// TODO Auto-generated method stub 3System.out.println(filename); 4 5File file=new File(filename); 6Reader readfile=null; 7int c_num=0; 8try{ 9readfile = new InputStreamReader(new FileInputStream(file)); 10int tempchar; 11while ((tempchar=readfile.read()) != -1) { 12if((char)tempchar!='\r'&&(char)tempchar!='\n'){ 13c_num++; 14} 15} 16readfile.close(); 17} 18catch(Exception e){ 19e.printStackTrace(); 20System.out.println("指定輸入檔案不存在"); 21} 22return c_num; 23}
3.單詞統計:(這裡面我用IsLetter來判斷字母的大小寫)
1 private static int num_of_word(String filename){ 2File file=new File(filename); 3Reader readfile=null; 4boolean letter_flag=false; 5int w_num=0; 6try{ 7readfile = new InputStreamReader(new FileInputStream(file)); 8int tempchar; 9while ((tempchar=readfile.read()) != -1) { 10if(IsLetter((char)tempchar)){ 11letter_flag=true; 12} 13else if(letter_flag==true){ 14letter_flag=false; 15w_num++; 16} 17} 18readfile.close(); 19} 20catch(Exception e){ 21System.out.println("指定輸入檔案不存在"); 22} 23return w_num; 24}
4.行數統計:(遇到換行符就加一。Windows中的換行符為“\r\n”,這裡只使用"\n"。)
1 private static int num_of_line(String filename) { 2// TODO Auto-generated method stub 3File file=new File(filename); 4Reader readfile=null; 5int l_num=1; 6try{ 7readfile = new InputStreamReader(new FileInputStream(file)); 8int tempchar; 9while ((tempchar=readfile.read()) != -1) { 10if((char)tempchar=='\n'){ 11l_num++; 12} 13} 14readfile.close(); 15} 16catch(Exception e){ 17System.out.println("指定輸入檔案不存在"); 18} 19return l_num; 20}
5.空行、程式碼行、註釋行統計:(按行讀檔案,去除每一行的換行符和空格,獲得的string長度為0就代表空行;一行中如果只有“{/*”、“{//”、“//”、“/*”代表註釋行(這些就是註釋的開頭),直到統計到註釋的末尾;其餘的均為程式碼行。)
1 private static int [] code_ana(String filename){ 2File file=new File(filename); 3int nothing=0; 4int line=0; 5int note=0; 6int code_line=0; 7boolean note_flag=false; 8BufferedReader readfile = null; 9try{ 10readfile = new BufferedReader(new FileReader(file)); 11String tempString = null; 12while ((tempString = readfile.readLine()) != null) { 13line++; 14tempString=tempString.replaceAll("\r\n"," ");//去掉所有換行符和空格 15if(note_flag==true){ 16note++; 17if(tempString.endsWith("*/")){ 18note_flag=false;//代表註釋內容在本行結束 19} 20} 21if(tempString.equals(" ")||tempString.equals("{")||tempString.equals("}")){ 22nothing++; 23} 24if(tempString.startsWith("//")||tempString.startsWith("{//")){ 25note++; 26} 27if(tempString.startsWith("/*")||tempString.startsWith("{/*")){ 28if(tempString.endsWith("*/")){ 29note++; 30} 31else{ 32note++; 33note_flag=true;//代表註釋的內容在本行還沒結束 34} 35} 36code_line=line-note-nothing; 37} 38readfile.close(); 39} 40catch(Exception e){ 41System.out.println("指定輸入檔案不存在"); 42} 43int []num =new int[3]; 44num[0]=code_line; 45num[1]=nothing; 46num[2]=note; 47return num; 48}
7.功能呼叫模組(這裡通過judge得到的功能需求,然後呼叫功能模組執行相應的操作):
1 private static void work() { 2// TODO Auto-generated method stub 3if(o_flag==true){ 4if(all_flag==false) 5System.out.println("命令格式不正確:有輸出指令但是沒有指定輸出檔案"); 6} 7 8if(a_flag==true){ 9String Command="程式碼行/空行/註釋行"; 10int []num=code_ana(file_name); 11System.out.print(txt_name+","+Command+":"+num[0]+"/"+num[1]+"/"+num[2]+"\r\n"); 12} 13 14if(c_flag==true){ 15String Command="字元數"; 16System.out.print(txt_name+","+Command+":"+num_of_char(file_name)+"\r\n"); 17} 18 19if(l_flag==true){ 20String Command="行數"; 21System.out.print(txt_name+","+Command+":"+num_of_line(file_name)+"\r\n"); 22} 23 24if(all_flag==true){ 25if(a_flag==true){ 26String Command="程式碼行/空行/註釋行"; 27code_output(output_name,Command,code_ana(file_name)); 28} 29if(c_flag==true){ 30String Command="字元數"; 31output(output_name,Command,num_of_char(file_name)); 32} 33if(w_flag==true){ 34String Command="單詞數"; 35output(output_name,Command,num_of_word(file_name)); 36} 37if(l_flag==true){ 38String Command="行數"; 39output(output_name,Command,num_of_line(file_name)); 40} 41System.out.println("執行並且輸出內容儲存成功"); 42} 43else { 44System.out.println("本指令沒有指定輸出檔案,所以輸出內容沒有儲存"); 45} 46}
六.測試用例:
這裡我們用的是idea:直接通過傳入引數的不同來測試每一種功能以及他們的組合:
下面是我用的輸入檔案:
1)-c input.txt -o output.txt:
2)-w input.txt -o output.txt:
3)-l input.txt -o output.txt:
4)-a input.txt -o output.txt:
5)-a -w -l -c input.txt -o output.txt:
6) -s -w -l D:/test/*.txt -o output.txt:這裡我們是在一個資料夾裡向下遞迴查詢符合要求的txt檔案:
七.參考文獻
《構建之法--現代軟體工程》 --鄒新 [第三版]
PS:(本次專案還有一些功能沒有實現)未完待續......