1. 程式人生 > >c#實現wc基本功能和擴展功能

c#實現wc基本功能和擴展功能

length lan soft 表格 command 這一 play nal 就會

c#實現wc基本功能和擴展功能

github:鏈接

一、項目要求

wc.exe 是一個常見的工具,它能統計文本文件的字符數、單詞數和行數。這個項目要求寫一個命令行程序,模仿已有wc.exe 的功能,並加以擴充,給出某程序設計語言源文件的字符數、單詞數和行數。
實現一個統計程序,它能正確統計程序文件中的字符數、單詞數、行數,以及還具備其他擴展功能,並能夠快速地處理多個文件。
基本功能列表:
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]: 文件或目錄名,可以處理一般通配符。

二、開發前PSP表格預估

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 60 60
· Estimate · 估計這個任務需要多少時間 60 60
Development 開發 800 860
· Analysis · 需求分析 (包括學習新技術) 120 140
· Design Spec · 生成設計文檔 60 60
· Design Review · 設計復審 (和同事審核設計文檔) 60 60
· Coding Standard · 代碼規範 (為目前的開發制定合適的規範) 30 40
· Design · 具體設計 30 60
· Coding · 具體編碼 350 290
· Code Review · 代碼復審 30 30
· Test · 測試(自我測試,修改代碼,提交修改) 120 180
Reporting 報告 150 150
· Test Report · 測試報告 100 100
· Size Measurement · 計算工作量 30 30
· Postmortem & Process Improvement Plan · 事後總結, 並提出過程改進計劃 20 20
合計 1010 1070

三、項目設計思路

  • 主函數
    從控制臺獲得鍵盤輸入的命令字符串,用Split屬性根據空格對其分解為命令字符串數組,數組長度最後一位為文件名,其余為命令參數數組。

  • 函數
    • getCommand:利用foreach語句讀取命令參數數組的每一個命令,匹配進行對應的操作。同時實現-s參數命令
    • count:實現-c -w -l 參數命令
    • extendCount:實現-a參數命令
    • display:根據參數輸出結果
  • 參數實現部分
    • -c:文件流的Length屬性
    • -w:利用正則表達式將除漢字、小寫字母、大寫字母、0~9、“.”以外的字符全都用空格代替,再將多個連續空格用一個空格代替,計算空格數
    • -l:計算“\r”的數目
    • -a: 利用Trim()除去具體某一行的多余空格,若該行長度小於等於1則空行數+1;若判斷存在“\”則註釋行數+1;出此兩行之外的稱為代碼行
      • -s: 根據“”分解文件路徑,字符串數組最後一位為含通配符的文件名

四、主要代碼實現

Main

static void Main(string[] args)
    {
        string command = "";
        while (command != "exit")
        {
            Console.Write("wc.exe ");
            command = Console.ReadLine();               // 得到輸入命令
            string[] commandSplitArray = command.Split(‘ ‘); // 分割命令
            int commandLength = commandSplitArray.Length;
            string[] parameterArray = new string[commandLength - 1];// 獲取命令參數數組
            for (int i = 0; i < commandLength - 1; i++)
            {
                parameterArray[i] = commandSplitArray[i];
            }
            string fileName = commandSplitArray[commandLength - 1];// 獲取文件名
            Console.WriteLine();
            WC wc = new WC();
            wc.getCommand(parameterArray, fileName);//執行

        }

    }

count

        FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
        charCount = (int)fs.Length;
        fs.Position = 0;
        StreamReader reader = new StreamReader(fs);
        string streamToString = reader.ReadToEnd();
        lineCount = streamToString.Split(‘\r‘).Length;
        streamToString = Regex.Replace(streamToString, "[^\u4e00-\u9fa5a-zA-z0-9.].*?", " ");
        streamToString = Regex.Replace(streamToString, "\\s{2,}", " ");
        wordCount = streamToString.Split(‘ ‘).Length;

-a

    FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
    StreamReader sr = new StreamReader(fs);
    String line;
    int nullLineCount = 0;
    int codeLineCount = 0;
    int noteLineCount = 0;
    while ((line = sr.ReadLine()) != null)
    {
    line = line.Trim(‘ ‘);
    line = line.Trim(‘\t‘);//   除去每行開頭多余空格和格式控制字符
    if (line == "" || line.Length <= 1)//   空行
                {
                    nullLineCount++;
                }
                else if (line.Substring(0, 2) == "//" || line.Substring(1, 2) == "//")//   註釋行
       {
       noteLineCount++;
      }
       else
       {
       codeLineCount++; // 代碼行
      }
      }
     sr.Close();

-s

    string[] fileNameArray = fileName.Split(‘\\‘);
                        string path = "";
                        for (int i = 0; i < fileNameArray.Length - 1; i++)
                        {
                            fileNameArray[i] = fileNameArray[i] + "\\";
                            path += fileNameArray[i];
                        }//獲取路徑
                        string tpfFileName = fileNameArray[fileNameArray.Length - 1];//獲取通配符
                        string[] files = Directory.GetFiles(path, tpfFileName);
                        foreach (string file in files)
                        {                                

                            fileNamep = file;
                            count(file);
                            extendCount(file);
                            display();
                            
                        }

測試
技術分享圖片
技術分享圖片
技術分享圖片

五、總結

這次的作業花費的時間比想象中多,也比想象中難。一開學就認真的完成作業可以讓人很快進入學習的狀態。在這次作業裏,我發現了自己的技術遠遠不足別人,所學的知識不加以運用一小段時間就會很陌生,同時發現自己要學習的東西還有太多太多。
在這次作業裏,我重新學習了IO流和正則表達式的使用,並學會運用git工具階段性地看到自己的進步,收獲了學習的樂趣。

c#實現wc基本功能和擴展功能