WordCount(功能实现、单元测试)

一、项目简介

1、Gitee项目地址:https://gitee.com/xnsy/WC

2、开发语言:C#

3、解题思路

刚看完作业要求后,只知道这个程序要完成对文件的统计工作,但是对于程序设计仍然是一头雾水,而后百度了怎么编写wordcount程序后,发现有很多优秀的博客和文章,都详细地写了程序的相关设计包括具体的代码和项目完成截图,因为并没有接触过Java编程,所以我选择了用C#

题目分析:

1.从程序的流程看,是一个控制台程序

2.要求对文件进行统计字数,涉及到文件读写

3.文件的扩展功能

通过各个方面查资料后我设计了以下四个功能函数

public string Operator(string[] sParameter, string sFilename)//基本功能实现

private void BaseCount(string filename)// 统计基本信息:字符数 单词数 行数

private void SuperCount(string filename) //统计高级信息:空行数 代码行数 注释行数

private string Display()//展示信息

二、设计实现

代码整体主要分为三个类:Main,功能,统计信息,展示

1、Main

主要负责基本功能的实现,在基本功能中,用户通过输入命令行的方式与程序实现交互。

 

 static void Main(string[] args)
        {
            string message = ""; // 存储用户命令
            while (message != "exit")
            {
                Console.Write("wc.exe ");
                // 得到输入命令
                message = Console.ReadLine();
                message = message.Trim(' ');
                message = message.Trim('\t');
                if (message != "-x")
                {
                    // 分割命令
                    string[] arrMessSplit = message.Split(' ');
                    int iMessLength = arrMessSplit.Length;
                    string[] sParameter = new string[iMessLength - 1];
                    // 获取命令参数
                    for (int i = 0; i < iMessLength - 1; i++)
                    {
                        sParameter[i] = arrMessSplit[i];
                    }
                    // 获取文件名
                    string sFilename = arrMessSplit[iMessLength - 1];
                    // 新建处理类
                    WC newwc = new WC();
                    newwc.Operator(sParameter, sFilename);
                }
                else
                {
                    string[] sParameter = new string[1];
                    sParameter[0] = message;
                    WC newwc = new WC();
                    newwc.Operator(sParameter, "");
                }
            }
        }

 

 

2、统计

Operator()方法中,捕捉 "-c""-w""-l"命令,通过参数素组的设置调用不同的类方法进行处理;Display()方法用来打印输出信息; BaseCount() 方法用以统计指定文件的字符数、单词数以及总行数。

 

public class WC
    {
        private string sFilename;    // 文件名
        private string[] sParameter; // 参数数组  
        private int iCharcount;      // 字符数
        private int iWordcount;      // 单词数
        private int iLinecount;      // 行  数
        private int iNullLinecount;  // 空行数
        private int iCodeLinecount;  // 代码行数
        private int iNoteLinecount;  // 注释行数

        // 初始化
        public WC()
        {
            this.iCharcount = 0;
            this.iWordcount = 0;
            this.iLinecount = 0;
            this.iNullLinecount = 0;
            this.iCodeLinecount = 0;
            this.iNoteLinecount = 0;
        }
        // 控制信息
        public string Operator(string[] sParameter, string sFilename)
        {
            this.sParameter = sParameter;
            this.sFilename = sFilename;

            string retrun_str = "";

            foreach (string s in sParameter)
            {
                if (s == "-x")
                {
                    string resultFile = "";
                    OpenFileDialog fd = new OpenFileDialog();
                    fd.InitialDirectory = "D:\\Patch";
                    fd.Filter = "All files (*.*)|*.*|txt files (*.txt)|*.txt";
                    fd.FilterIndex = 2;
                    fd.RestoreDirectory = true;
                    if (fd.ShowDialog() == DialogResult.OK)
                    {
                        resultFile = fd.FileName;
                        //Console.WriteLine("文件名:{0}", resultFile);
                        SuperCount(resultFile);
                        BaseCount(resultFile);
                        retrun_str = DisplayAll();
                    }
                    break;
                }
                // 遍历文件
                else if (s == "-s")
                {
                    try
                    {
                        string[] arrPaths = sFilename.Split('\\');
                        int pathsLength = arrPaths.Length;
                        string path = "";

                        // 获取输入路径
                        for (int i = 0; i < pathsLength - 1; i++)
                        {
                            arrPaths[i] = arrPaths[i] + '\\';

                            path += arrPaths[i];
                        }

                        // 获取通配符
                        string filename = arrPaths[pathsLength - 1];

                        //  获取符合条件的文件名
                        string[] files = Directory.GetFiles(path, filename);

                        foreach (string file in files)
                        {
                            //Console.WriteLine("文件名:{0}", file);
                            SuperCount(file);
                            BaseCount(file);
                            retrun_str = Display();
                        }
                        break;
                    }
                    catch (IOException ex)
                    {
                        //Console.WriteLine(ex.Message);
                        return "";
                    }
                }
                // 高级选项
                else if (s == "-a")
                {
                    //Console.WriteLine("文件名:{0}", sFilename);
                    SuperCount(sFilename);
                    BaseCount(sFilename);
                    retrun_str = Display();
                    break;
                }
                //  基本功能
                else if (s == "-c" || s == "-w" || s == "-l")
                {
                    //Console.WriteLine("文件名:{0}", sFilename);
                    BaseCount(sFilename);
                    retrun_str = Display();
                    break;
                }
                else
                {
                    //Console.WriteLine("参数 {0} 不存在", s);
                    break;
                }
            }
            Console.WriteLine("{0}", retrun_str);
            return retrun_str;
        }

        // 统计基本信息:字符数 单词数 行数
        private void BaseCount(string filename)
        {
            try
            {
                // 打开文件
                FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                StreamReader sr = new StreamReader(file);
                int nChar;
                int charcount = 0;
                int wordcount = 0;
                int linecount = 0;
                //定义一个字符数组
                char[] symbol = { ' ', ',', '.', '?', '!', ':', ';', '\'', '\"', '\t', '{', '}', '(', ')', '+' ,'-',
                  '*', '='};
                while ((nChar = sr.Read()) != -1)
                {
                    charcount++;     // 统计字符数

                    foreach (char c in symbol)
                    {
                        if (nChar == (int)c)
                        {
                            wordcount++; // 统计单词数
                        }
                    }
                    if (nChar == '\n')
                    {
                        linecount++; // 统计行数
                    }
                }
                iCharcount = charcount;
                iWordcount = wordcount + 1;
                iLinecount = linecount + 1;
                sr.Close();
            }
            catch (IOException ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
        }

        // 统计高级信息:空行数 代码行数 注释行数
        private void SuperCount(string filename)
        {
            try
            {
                // 打开文件
                FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                StreamReader sr = new StreamReader(file);
                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++;
                    }
                }
                iNullLinecount = nulllinecount;
                iCodeLinecount = codelinecount;
                iNoteLinecount = notelinecount;
                sr.Close();
            }
            catch (IOException ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
        }

3、展示统计完成的信息

 

  private string Display()
        {
            string return_str = "";

            foreach (string s in sParameter)
            {
                if (s == "-c")
                {
                    //Console.WriteLine("字 符 数:{0}", iCharcount);
                    return_str += "字符数:" + iCharcount.ToString();
                }
                else if (s == "-w")
                {
                    //Console.WriteLine("单 词 数:{0}", iWordcount);
                    return_str += "单词数:" + iWordcount.ToString();
                }
                else if (s == "-l")
                {
                    //Console.WriteLine("总 行 数:{0}", iLinecount);
                    return_str += "总行数:" + iLinecount.ToString();
                }
                else if (s == "-a")
                {
                    return_str += "空行数:" + iNullLinecount.ToString();
                    return_str += "代码行数:" + iCodeLinecount.ToString();
                    return_str += "注释行数:" + iNoteLinecount.ToString();
                }
            }
            //Console.WriteLine();
            return return_str;
        }

 

三、单元测试

黑盒测试

 

(1)   对单词数进行统计

 

 

(2)   对行数进行统计

 

 

(3)   对字符进行统计

 

(4)   对扩展功能的测试

 

(5)   总测试

 

 

void WCTest()对程序进行单元测试

(1)通过字符数:94进行正确测试

 

(2)通过字符数:100等错误信息测试看测试是否通过

 

 

四、总结

 

     刚拿到这个项目的时候其实一头雾水,无从下手,编写代码的过程中也遇到很多的问题,出现无法预料的错误。经常在一个地方卡住卡很久。不过通过这次个人项目,我也收获了很多,比如程序的设计实现需要先设计再去实现,设计和编译一样重要,完成任何一个程序,需要实现设计方案,避免后面的错误和程序不完善等问题。同时,代码的测试也占有相当的比例,通过各方面的测试避免程序出现错误和对用户体验度的完善。最后,完成一个完整的程序的时候,一定的代码功底就显得尤为重要,这是需要不停积累的练习的。

 

参考文献

C#单元测试

 

廖雪峰的官方网站

 

posted @ 2018-09-24 20:34  十七阿  阅读(846)  评论(0编辑  收藏  举报