c#实现wc基本功能和扩展功能

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工具阶段性地看到自己的进步,收获了学习的乐趣。

猜你喜欢

转载自www.cnblogs.com/runll/p/9638212.html
今日推荐