1. 程式人生 > >WC項目反思與總結

WC項目反思與總結

項目 字母 通道 耗時 name 表達式 ESS 題目 保存

1. 項目需求說明

WordCount的需求可以概括為:對程序設計語言源文件統計字符數、單詞數、行數,統計結果以指定格式輸出到默認文件中,以及其他擴展功能,並能夠快速地處理多個文件。
可執行程序命名為:wc.exe,該程序處理用戶需求的模式為:
wc.exe [parameter] [input_file_name]
存儲統計結果的文件默認為result.txt,放在與wc.exe相同的目錄下。

1. 1 基本功能:

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
註意:
空格,水平制表符,換行符,均算字符。
由空格或逗號分割開的都視為單詞,且不做單詞的有效性校驗,例如:thi#,that視為用逗號隔開的2個單詞。
-c, -w, -l參數可以共用同一個輸入文件,形如:wc.exe –w –c file.c 。
-o 必須與文件名同時使用,且輸出文件必須緊跟在-o參數後面,不允許單獨使用-o參數。

舉例:

wc.exe –c file.c,則輸出結果保存在result.txt中,內容格式如下(註意大小寫):
file.c, 字符數: 50

wc.exe –w file.c,則輸出結果保存在result.txt中,內容格式如下(註意大小寫):
file.c, 單詞數: 30

wc.exe –l file.c,則輸出結果保存在result.txt中,內容格式如下(註意大小寫):
file.c, 行數: 10

wc.exe –l –c file.c,則統計file.c中的字符數和行數,輸出結果保存在result.txt中,內容格式如下:
file.c, 字符數: 50
file.c, 行數: 10

2. 編碼過程

  • Gitee項目

  • PSP表格

PSP2.1 PSP階段 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 10 1
· Estimate · 估計這個任務需要多少時間 10 1
Development 開發 720 635
· Analysis · 需求分析 (包括學習新技術) 10 5
· Design Spec · 生成設計文檔 30 40
· Design Review · 設計復審 (和同事審核設計文檔) 10 0
· Coding · 代碼規範 (為目前的開發制定合適的規範) 10 0
· Code Review · 具體設計 10 5
· Test · 具體編碼 610 540
Reporting · 代碼復審 10 5
· Test Report 報告 30 40
· Size Measurement · 測試報告 30 10
· Postmortem & Process · 計算工作量 10 0
Improvement Plan · 事後總結, 並提出過程改進計劃 10 5
合計 770 656

2. 1 解題思路

剛拿到題目時,我先看了題目需求,並列出主要要實現的功能:
1. 讀取文件內容
2. 計算字符數
3. 計算單詞數
4. 計算行數
5. 向文件寫入內容
經過主要的功能分析後,我決定用我比較熟悉的java語言來完成這個題目。

其次,我分析了用java語言完成該題目主要需要運用的知識是:文件的IO流部分的知識。
於是我復習了我自己學習java IO字符流模塊的知識和筆記,相關筆記如下:


/*
------------|   Reader    抽象類    輸入字符流的基類
-----------------------|   FileReader    讀取文件的輸入字符流

FileReader的步驟:

    1. 找到目標文件
    2. 建立數據輸入字符流通道
    3. 讀取數據

*/

package cn.itcast.charstream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Demo1 {
       public static void main(String[] args) throws IOException {
             read1();
             read2();
       }
       public static void read1() throws IOException {
             File file = new File("E:/作業/Java/文件/b.txt");
             FileReader fileReader = new FileReader(file);
             int content = 0;
             while((content = fileReader.read()) != -1){//每次讀一個字符
                    System.out.print((char)content);
             }
             fileReader.close();
       }
       public static void read2() throws IOException {
             File file = new File("E:/作業/Java/文件/b.txt");
             FileReader fileReader = new FileReader(file);
             //建立緩沖字符數組
             char[] buf = new char[1024];
             int length = 0;
             while((length = fileReader.read(buf)) != -1)
             {
                    System.out.println(new String(buf, 0, length));
             }
       }
}


/*
--------------|    Write    抽象類    輸出字符流的基類
--------------------------|    FileWriter    向文件數據輸出數據的輸出字符流

FileWriter 的使用步驟:

    1. 找到目標文件
    2. 建立字符輸出流通道
    3. 輸出數據
    4. 關閉文件




註意:

    1. filewriter底層維護了一個1024的字符數組,寫的數據先存在該數組中,當調用flush或close方法或填滿了數組才會保存到硬盤上。
    2. new FileWriter(file);    如果目標文件不存在,會自動創建。
    3. new FileWriter(file);默認先清空數據。如果要直接添加數據,使用FileWriter(File,true)。

*/

package cn.itcast.charstream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo2 {
       public static void main(String[] args) throws IOException {
             write();
       }
       public static void write() throws IOException {
             File file = new File("E:/作業/Java/文件/b.txt");
             FileWriter fileWriter = new FileWriter(file);
             String data = "今天很開心";
             fileWriter.write(data);
             fileWriter.close();
       }
}


然後,我又思考發現,在計算單詞數的時候,可以通過正則表達式來截取字符串的方式計算單詞數量,
所有我又復習了正則表達式的相關用法,相關示例如下:


    範圍詞

            [abc]                        出現的只能是abc其中的一個
            [^abc]                      出現的只能是除了abc 的一個任意字符
            [a-z1-9&$]                    出現的只能是兩頭字母包括在內的字符(即:a~z  或1~9 或&或$)

2. 2 程序設計實現過程

在實際編碼中,我使用了四個類,其類名和相關用途如下:
BaseCount:解析用戶輸入的命令行、調用JudgeOption類
相關方法:
wordCountMain()

BaseFunc:實現計算字符數、單詞書、行數這三個方法
相關方法:
count_charsNum(String path)
count_wordsNum(String path)
count_linesNum(String path)

JudgeOption:判斷用戶輸入參數,調用BaseFunc中對應的相關方法
相關方法:
judge(String arg, String readPath, String writePath)

WriteCount:把計算後的結果寫出到指定文件
相關方法:
writeCount(String str, String path)
initFile(String path):如果寫出的文件存在,將文件內容清空

2. 3 代碼說明


public class BaseFunc {
    public static int count_charsNum(String path){
        int count = 0;
        try {
            FileReader fileReader = new FileReader(path);
            char[] buf = new char[1024];
            int length = 0;
            while( (length = fileReader.read(buf)) != -1){
                count += length;
            }
            fileReader.close();
        } catch (FileNotFoundException e) {
            System.out.println("");
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return count;
    }
    
    public static int count_wordsNum(String path) {
        int count = 0;
        
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
              while(br.read()!=-1) 
              {
               String s = br.readLine();
               
               for(int i=0; i<s.split("[^a-zA-Z]").length; i++){
                   
                   if( !s.split("[^a-zA-Z]")[i].isEmpty()){
                       count ++;
                   }
               }
               
               
              }
              br.close(); 
        }  catch (Exception e) {
            System.out.println(e);
        }
        
        
        return count;
        
    }
    public static int count_linesNum(String path) {
        int count = 0;
        
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
            while(br.read()!=-1) 
            {
                String s = br.readLine();
                
                count++;
            }
            br.close(); 
        }  catch (Exception e) {
            System.out.println(e);
        }
        
        
        return count;
        
    }
}



public class JudgeOption {
    public static void judge(String arg, String readPath, String writePath) {
        int count = 0;
        String str = "";
        
        switch (arg) {
        case "-c":
        case "—c":
            count = BaseFunc.count_charsNum(readPath);
            str = readPath.split("/")[ (readPath.split("/").length-1) ];
            str += ", 字符數:";
            str += count;
            WriteCount.writeCount(str, writePath);
            break;
            
        case "-w":
        case "—w":
            count = BaseFunc.count_wordsNum(readPath);
            str = readPath.split("/")[ (readPath.split("/").length-1) ];
            str += ", 單詞數:";
            str += count;
            WriteCount.writeCount(str, writePath);
            break;
            
        case "-l":
        case "—l":
            count = BaseFunc.count_linesNum(readPath);
            str = readPath.split("/")[ (readPath.split("/").length-1) ];
            str += ", 行數:";
            str += count;
            WriteCount.writeCount(str, writePath);
            break;
            
        }
    }
}

WC項目反思與總結