一、项目简介
1、Gitee项目地址:
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" 命令,通过参数素组的设置调用不同的类方法进行处理;
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; }
BaseCount() 方法用以统计指定文件的字符数、单词数以及总行数;
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; } }
Display()方法用来打印输出信息;
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; }
3、展示统计完成的信息
private string DisplayAll() { string return_str = ""; foreach (string s in sParameter) { //Console.WriteLine("字 符 数:{0}", iCharcount); //Console.WriteLine("单 词 数:{0}", iWordcount); //Console.WriteLine("总 行 数:{0}", iLinecount); //Console.WriteLine("空 行 数:{0}", iNullLinecount); //Console.WriteLine("代码行数:{0}", iCodeLinecount); //Console.WriteLine("注释行数:{0}", iNoteLinecount); return_str += "字符数:" + iCharcount.ToString(); return_str += "单词数:" + iWordcount.ToString(); return_str += "总行数:" + iLinecount.ToString(); return_str += "空行数:" + iNullLinecount.ToString(); return_str += "代码行数:" + iCodeLinecount.ToString(); return_str += "注释行数:" + iNoteLinecount.ToString(); } //Console.WriteLine(); return return_str; }
三、单元测试
1、黑盒测试
(1) 对单词数进行统计
(2) 对行数进行统计
(3) 对字符进行统计
(4) 对扩展功能的测试
(5) 总测试
void WCTest()对程序进行单元测试
(1)通过字符数:94进行正确测试
(2)通过字符数:100等错误信息测试看测试是否通过
四、总结
刚拿到这个项目的时候其实一头雾水,无从下手,编写代码的过程中也遇到很多的问题,出现无法预料的错误。经常在一个地方卡住卡很久。不过通过这次个人项目,我也收获了很多,比如程序的设计实现需要先设计再去实现,设计和编译一样重要,完成任何一个程序,需要实现设计方案,避免后面的错误和程序不完善等问题。同时,代码的测试也占有相当的比例,通过各方面的测试避免程序出现错误和对用户体验度的完善。最后,完成一个完整的程序的时候,一定的代码功底就显得尤为重要,这是需要不停积累y与练习的。