WorkCount

https://gitee.com/Damocleses/wc/

解题思路:当我看到作业要求时,我首先想到的是从零到整,首先完成最基础的功能

首先是准备的一些变量,后面要用到

        static string fileName;  //操作的文件名
        static string ResultFile = "result.txt";//储存结果的文件,没有-o参数时默认为result.txt
        //用于计数
        static int aChar = 0;
        static int aWord = 0;
        static int aLine = 0;
        static int aCode = 0;
        static int aNote = 0;
        static int aEmpty = 0;

        //用于检测是否有对应参数
        static int fChar = 0;
        static int fWord = 0;
        static int fOutput = 0;
        static int fLine = 0;
        static int fMore = 0;
        static int fRecursion = 0;

我把每个功能都写到一个方法中

首先肯定要对参数输入进行检测

        static bool Check(string[] args)
        {
            int i;
            fileName = args[args.Length - 1];   //如果没有-o参数,则操作文件为最后一个参数
            //对参数进行检查           
            for (i = 0; i < args.Length; i++)
            {
                //检查是否输入了多个参数
                if (args[i] == "-c")
                { fChar++; }
                else if (args[i] == "-w")
                { fWord++; }
                else if (args[i] == "-o")
                { fOutput++; }
                else if (args[i] == "-l")
                { fLine++; }
                else if(args[i] == "-a")
                { fMore++; }
                else if(args[i] == "-s")
                { fRecursion++; }

                if (args[i] == "-o")
                {
                    if (args.Length <= 2)
                    {
                        Console.WriteLine("错误的命令,若使用-o参数请先在前面使用-c或-w或-i或-l指令");
                        return false;
                    }
                    fileName = args[i - 1];     //-o参数前一个参数必定为操作文件
                    ResultFile = args[i + 1];   //-o参数后一个参数必定为储存文件
                }
            }
            if (fChar > 1 || fWord > 1 || fOutput > 1)
            {   //如果大于一表示输入了至少两个重复参数
                Console.WriteLine("输入的参数不能重复,请修改后再输入");
                return false;
            }

            if (!Regex.IsMatch(fileName, "\\w*\\.(txt|c|docx)"))
            {   //检查操作的文件格式
                Console.WriteLine("Wrong filename,please try again!\nparam:-o,filename:{0}", fileName);
                Console.WriteLine("Allowed FileName:*.(txt|c|docx");
                return false;
            }
            else if (!Regex.IsMatch(ResultFile, "\\w*\\.(txt|c|docx)"))
            {   //检查储存文件格式
                Console.WriteLine("Wrong filename,please try again!\nparam:-o,filename:{0}", ResultFile);
                Console.WriteLine("Allowed FileName:*.(txt|c|docx");
                return false;
            }

            //所有的格式没问题后检查文件是否存在
            if(!File.Exists(fileName))
            {
                if (!Regex.IsMatch(fileName, "\\*\\.(txt|c|docx)"))
                {
                    Console.WriteLine("文件不存在!请重新输入");
                    return false;
                }
            }
            return true; //一切OK
        }

其次是基础功能

        /// <summary>
        /// 字符计数
        /// </summary>

        static void CharCount()
        {
            StreamReader content = new StreamReader(fileName);
            char[] output = content.ReadToEnd().ToCharArray();  //将字符串流保存到char数组中
            content.Close();
            File.AppendAllText(ResultFile, fileName + ",字符数:" + output.Length.ToString() + "\n");    //保存到result.txt中              
            aChar = output.Length;
        }

基础功能大同小异,思路就是从文件中读取数据流,进行对应处理后计数,然后保存数字。单词和行数同理就不提了

然后是扩展功能,对应算法如下

        /// <summary>
        /// 代码行、空行、注释行计数
        /// </summary>

        static void MoreCount()
        {
            string[] More = File.ReadAllText(fileName).Split('\n');
            int i = 0;
            char[] chr;
            for(i = 0;i < More.Length;i++)
            {
                chr = More[i].Replace(" ", "").Replace("\t","").ToCharArray();   //去掉空格和制表符
                if(chr.Length > 1)
                {   //字符数大于一,可能是代码行,可能是注释行
                    if(chr[0] == '}' || chr[0] == '{' && chr[1] == '/' && chr[2] == '/')
                    {   //去掉空格后如果包括{或}加上//则为注释行
                        aNote++;
                    }
                    else
                    {   //否则是代码行
                        aCode++;
                    }
                       
                }
                else
                {   //去掉空行后字符数小于一,则是空行
                    aEmpty++;
                }
            }
            string print = string.Format("代码行/空行/注释行:{0}/{1}/{2}\n", aCode, aEmpty, aNote);
            File.AppendAllText(ResultFile, print);
        }

然后是循环处理满足条件的文件

        /// <summary>
        /// 用于递归处理目录下符合条件的文件
        /// </summary>
        static void Recursion()
        {
            List<FileInfo> file = GetAllFilesInDirectory(".\\");  //GetAllFilesInDirectory是自定义方法,返回输入目录及其子目录的所有文件
            string[] suffix = fileName.Split('.');  //文件后缀
            string pattern = fileName.Replace("*.", "\\w*\\.").Replace(suffix[1], "") + "(" + suffix[1] + ")$";  //利用正则表达式挑选符合条件的文件
            foreach(var f in file)
            {  //循环每个文件
                    if (Regex.IsMatch(f.Name, pattern))
                {        //符合条件则全部方法都调用一遍
                    fileName = f.Name;
                    //根据参数决定该调用哪些方法
                    if (fChar > 0)
                        CharCount();    //字符计数
                    if (fWord > 0)
                        WordsCount();   //单词计数
                    if (fLine > 0)
                        LinesCount();   //行数计数
                    if (fMore > 0)
                        MoreCount();    //代码行、空行、注释行计数

                    Print();    //将结果输出到屏幕
                }
            }
        }

由于-c -w -l都有在屏幕显示的功能,故我写在一个方法中

        static void Print()
        {
            if (fChar > 0)
                Console.WriteLine(fileName + ",字符数:" + aChar.ToString());
            if(fWord > 0)
                Console.WriteLine(fileName + ",单词数:" + aWord.ToString());
            if(fLine > 0)
                Console.WriteLine(fileName + ",行数:" + aLine.ToString());
            if (fMore > 0)
            {
                string print = string.Format("代码行/空行/注释行:{0}/{1}/{2}", aCode, aEmpty, aNote);
                Console.WriteLine(print);
            }
        }

然后开始时主界面调用方法就行

        static void Main(string[] args)
        {
            //检查参数,此外-o参数在此方法已解决
            if(!Check(args))   
            {
                return;
            }

            //根据参数决定该调用哪些方法
            if (fRecursion > 0)
            {
                Recursion();    //循环
                return;
            }
            if (fChar > 0)
                CharCount();    //字符计数
            if (fWord > 0)
                WordsCount();   //单词计数
            if (fLine > 0)
                LinesCount();   //行数计数
            if (fMore > 0)
                MoreCount();    //代码行、空行、注释行计数

            Print();    //将结果输出到屏幕
        }

测试用例

文件:

目录文件:

运行结果

 

猜你喜欢

转载自www.cnblogs.com/damocleses/p/9697271.html