wordCount的c#实现
本次作业地址:https://edu.cnblogs.com/campus/xnsy/Test/homework/2203
(1)互审代码情况
在此次作业中,我们互相写了完整的wordCount代码后,互相进行了代码的审查,发现了很多问题,下列举几个模块审查问题
在合作同学的代码中他将对数据的处理写为一类,读写,操作,写出,写为一类,显得主函数太过冗长,我将代码的读入,操作,主函数归为三类
使得代码更为精简
基本功能概述:
wc.exe -c file.c //返回文件 file.c 的字符数
wc.exe -w file.c //返回文件 file.c 的单词总数
wc.exe -l file.c //返回文件 file.c 的总行数
wc.exe -o outputFile.txt //将结果输出到指定文件outputFile.txt
拓展功能概述:
wc.exe -a file.c //统计代码行/空行/注释行
wc.exe -s //调用其他-指令
注释:
代码行:本行包括多于一个字符的代码。
空 行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:}//注释
在这种情况下,这一行属于注释行。
如下图中的空行/注释行/代码行的计数方法中,我们发现将注释行的if语句嵌套,后对codecount的计数会发生影响
于是进行了改正:
还有很多不便一一赘述,将在下列测试中继续枚举。
项目实现
main函数类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WordCount
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("WordCount");
Console.WriteLine("统计字符数 wc.exe -c file.c ");
Console.WriteLine("统计单词总数 wc.exe -w file.c ");
Console.WriteLine("统计总行数 wc.exe -l file.c ");
Console.WriteLine("统计输出到文件 wc.exe -o file.c ");
Console.WriteLine("统计代码行/空行/注释行 wc.exe -a file.c ");
Console.WriteLine("调用其他-指令 wc.exe -s ");
Console.WriteLine("请输入指令:");
readFile readfile = new readFile();
readfile.Read();//调用读入文件类的Read()方法
Console.WriteLine();
Console.WriteLine("按任意键退出");
Console.ReadKey();
}
}
}
readFile类(对读取的命令进行操作的审查)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WordCount
{
class readFile
{
public string name = "";
public void Read()
{
string getcmd = "";
Console.Write("wc.exe ");
getcmd = Console.ReadLine();
this.check(getcmd);//调用审查命令函数,进行对cmd的操作是否错误的审查
}
string cmd = "";
public void check(string getcmd) //判断输入格式是否正确
{
try
{
this.name = getcmd;
string[] file = getcmd.Split(new char[1] { ‘ ‘ }, StringSplitOptions.RemoveEmptyEntries);//分割读取的文件名与操作
string filename = "";
bool isopen = true;
foreach (string s in file)
{
if(s.Length>2)
{
string[] f = s.Split(new char[1] { ‘.‘ }, StringSplitOptions.RemoveEmptyEntries);
//(f[f.Length - 1] != "c" && f[f.Length - 1] == "t") || (f[f.Length - 1] != "txt")
if(f[f.Length-1]!="c")
{
if(f[f.Length-1]!="txt")
{
isopen = false;
}
else
{
filename = s;
}
}
else
{
filename = s;
}
}
if (s.Length == 2 && s.Substring(0, 1) == "-")//判断是否为操作命令
{
cmd = cmd + s;
if (s != "-c" && s != "-w" && s != "-l" && s != "-a"&&s !="-s"&&s!="-o")//处理操作错误
{
isopen = false;
}
if (isopen == false)
{
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine(" 请输入正确的文件名或您的操作有误 ");
Console.WriteLine("----------------------------------------------------------");
this.Read();
break;
}
}
if (s.Length < 2)//处理操作错误
{
isopen = false;
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine(" 请输入正确的文件名或您的操作有误 ");
Console.WriteLine("----------------------------------------------------------");
this.Read();
break;
}
}
if (isopen == true&&cmd!="")
{
if (cmd.Contains("-s") == false)
{
this.openFilename(filename);
}
}
else
{
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine(" 请输入正确的文件名或您的操作有误 ");
Console.WriteLine("----------------------------------------------------------");
this.Read();
}
if(cmd.Contains("-s"))
{
handleFile hdfile = new handleFile();
hdfile.checkCmd(cmd);
}
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine(" 请输入正确的文件名或您的操作有误 ");
Console.WriteLine("----------------------------------------------------------");
this.Read();
}
}
public void openFilename(string name)//打开文件操作
{
FileStream fs = new FileStream(@name, FileMode.Open);
StreamReader sr = new StreamReader(fs);
string allStr = sr.ReadToEnd();
sr.Close();
fs.Close();
handleFile hdfile = new handleFile();//调用操作文件类
hdfile.allstr = allStr;
hdfile.cmd = cmd;
hdfile.name = name;
hdfile.checkCmd(cmd);
}
}
}
handleFile类(处理文件类)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace WordCount
{
class handleFile//处理文件
{
public string name = "";
public string allstr = "";
public string cmd = "";
public bool isout;
public void checkCmd(string cmdstr) //检查指令
{
if(cmdstr.Contains("-o"))//是否进行输出到outfile.txt的操作
{
this.isout = true;
}
else
{
this.isout = false;
}
if (cmdstr.Contains("-s"))
{
cmdstr = cmdstr.Replace("-s", "");
this.handleS(cmdstr);
}
else
{
for (int i = 0; i < cmdstr.Length; i++)//判断是什么命令
{
if (cmdstr[i] == ‘-‘)
{
if (cmdstr[i + 1] == ‘c‘)
{
this.handleC();
}
else if (cmdstr[i + 1] == ‘w‘)
{
this.handleW();
}
else if (cmdstr[i + 1] == ‘l‘)
{
this.handleL();
}
else if (cmdstr[i + 1] == ‘a‘)
{
this.handleA();
}
}
}
}
}
public void handleC()//调用正则表达式对字符数的统计进行审查
{
var cStr = this.allstr;
Regex re = new Regex(@"(\r\n)|(\S)|(\u0020)|(\u3000)"); //换行和回车符不是同一个
int count = re.Matches(this.allstr).Count;
Console.WriteLine();
Console.WriteLine(this.name+" "+ "字符数:"+count);
this.rstFile(Convert.ToString(this.name + " " + "字符数:" + count));
this.outputFile(Convert.ToString(this.name + " " + "字符数:" + count), this.isout);
}
public void handleW()
{
string wStr = this.allstr;
string[] sArray = wStr.Split(new char[3] { ‘ ‘, ‘,‘,‘\r‘ }, StringSplitOptions.RemoveEmptyEntries); //" "与","作为分割符
int count = 0;
foreach (string s in sArray)//遍历统计单词数量
{
count++;
}
Console.WriteLine();
Console.WriteLine(this.name + " " + "单词数:"+count);
this.rstFile(Convert.ToString(this.name + " " + "单词数:" + count));
this.outputFile(Convert.ToString(this.name + " " + "单词数:" + count), this.isout);
}
public void handleL()
{
FileStream fs = new FileStream(@name, FileMode.Open);
StreamReader sr = new StreamReader(fs);
int lines = 0;
while (sr.ReadLine() != null)//遍历统计行数(包含空行)
{
lines++;
}
sr.Close();
fs.Close();
Console.WriteLine(this.name + " " + "行数:"+lines);
this.rstFile(Convert.ToString(this.name + " " + "行数:" + lines));
this.outputFile(Convert.ToString(this.name + " " + "行数:" + lines), this.isout);
}
public void handleA()//空行/注释行/代码行的计数
{
FileStream fs = new FileStream(@name, FileMode.Open);
StreamReader sr = new StreamReader(fs);
string lines = "";
int nullcount = 0;
int notedcount = 0;
int codecount = 0;
while ((lines =sr.ReadLine()) != null)
{
lines = lines.Trim(‘ ‘);//每一行去掉两头空白字符
lines = lines.Trim(‘\t‘);//每一行去掉两头TAB字符
if (lines == "" || lines.Length <= 1)
{
nullcount++;//空行计数加一
}
else if (lines.Length > 2 && (lines.Substring(0, 2) == "//" || lines.Substring(1, 2) == "//"))
{
notedcount++;//注释行计数加一
}
else if (lines.Length == 2 && (lines.Substring(0, 2) == "//"))
{
notedcount++; //注释行计数加一
}
else
{
codecount++;//代码行计数加一
}
}
sr.Close();
fs.Close();
string outstr = this.name + " " + "空行/注释行/代码行:" + nullcount.ToString() + "/" + notedcount.ToString() + "/" + codecount.ToString();
Console.WriteLine();
Console.WriteLine(this.name + " "+"空行/注释行/代码行:" +@"{0}/{1}/{2}", nullcount, notedcount, codecount);
this.rstFile(outstr);
this.outputFile(outstr, this.isout);
}
public void handleS(string cmd)//-s命令调用其它命令函数
{
string rootPath = Directory.GetCurrentDirectory();
string[] files = Directory.GetFiles(rootPath, "*.c");
foreach (string file in files)
{
FileStream fs = new FileStream(@file, FileMode.Open);
StreamReader sr = new StreamReader(fs);
this.allstr = sr.ReadToEnd();
sr.Close();
fs.Close();
this.name = file;
this.checkCmd(cmd);
}
}
public void rstFile(string str)//输出函数
{
string filePath = Directory.GetCurrentDirectory();
StreamWriter sw = new StreamWriter(@filePath+"//"+"result.txt", true, Encoding.UTF8);
sw.WriteLine(str);
sw.Close();
}
public void outputFile(string str, bool isout)//-0命令,输出到output.txt
{
if (isout)
{
string filePath = Directory.GetCurrentDirectory();
StreamWriter sw = new StreamWriter(@filePath + "//" + "output.txt", true, Encoding.UTF8);
sw.WriteLine(str);
sw.Close();
}
}
}
}
性能测试
测试工具:VS2013的性能测试工具
原来对字符数等命令统计使用的是for循环遍历的方法
代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace WordCount
{
class DataProcess
{
//打开.c文件并将内容以字符串形式读取出来
public string openFile(string fstr)
{
FileStream fs = new FileStream(fstr, FileMode.Open);
byte[] array = new byte[fs.Length];
fs.Read(array,0, array.Length);
fs.Close();
string str = Encoding.UTF8.GetString(array);
return str;
}
//统计字符数
public int cProcess(string fstr)
{
string str = openFile(fstr);
int charCount = 0;
charCount = str.Length;
foreach(char c in str)
{
if(c==‘\n‘)
{
charCount--;
}
}
StreamWriter sw = new StreamWriter("result.txt", true);
sw.WriteLine(fstr + " 字符数: " + Convert.ToString(charCount));
sw.Close();
return charCount;
}
//统计行数
public int lProcess(string fstr)
{
string str = openFile(fstr);
int lineCount = 1;
foreach (char l in str)
{
if (l == ‘\n‘)
{
lineCount++;
}
}
StreamWriter sw = new StreamWriter("result.txt", true);
sw.WriteLine(fstr + " 行数: " + Convert.ToString(lineCount));
sw.Close();
return lineCount;
}
//统计单词书
public int wProcess(string lstr)
{
string str = openFile(lstr);
int count = 1;
bool isBlank = true;
foreach(char s in str)
{
if(s!=‘ ‘ && s!= ‘\n‘ &&s!=‘,‘&& isBlank==true)
{
count++;
isBlank = false;
}
else if((s==‘ ‘||s==‘\n‘||s==‘,‘)&&isBlank==false)
{
isBlank = true;
}
}
StreamWriter sw = new StreamWriter("result.txt", true);
sw.WriteLine(lstr + " 单词数:" + Convert.ToString(count - 1));
sw.Close();
return count - 1;
}
//统计代码行/空行/注释行
public string aProcess(string astr)
{
FileStream fs = new FileStream(astr, FileMode.Open);
StreamReader sr = new StreamReader(fs);
string lines = "";
int codeLineCount = 0;
int nullLineCount = 0;
int noteLineCount = 0;
while ((lines = sr.ReadLine()) != null)
{
lines = lines.Trim(‘ ‘);
lines = lines.Trim(‘\t‘);
if (lines == "" || lines.Length <= 1)
{
nullLineCount++;
}
else if (lines.Length > 2 && lines.Substring(0, 2) == "//" || lines.Substring(1, 2) == "//")
{
noteLineCount++;
}
else if(lines.Length==2 && lines.Substring(0, 2) == "//")
{
noteLineCount++;
}
else
{
codeLineCount++;
}
}
string complexLineCount = Convert.ToString(codeLineCount) + "/"+Convert.ToString(nullLineCount) +"/"+ Convert.ToString(noteLineCount);
StreamWriter sw = new StreamWriter("result.txt", true);
sw.WriteLine(astr + " 代码行/空行/注释行:" + Convert.ToString(codeLineCount)+"/"+Convert.ToString(nullLineCount)+"/"+Convert.ToString(noteLineCount));
sw.Close();
return complexLineCount;
}
//将统计的数据存入指定文件
public string oProcess(string oFile)
{
System.IO.File.WriteAllText(oFile, string.Empty);
string str = openFile("result.txt");
StreamWriter sw = new StreamWriter(oFile, true);
sw.WriteLine(str);
sw.Close();
return oFile;
}
}
}
对其进行性能测试
后改用正则表达式的方法,并在对其他代码进行优化后再进行性能测试
代码如下:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace WordCount { class handleFile//处理文件 { public string name = ""; public string allstr = ""; public string cmd = ""; public bool isout; public void checkCmd(string cmdstr) //检查指令 { if (cmdstr.Contains("-o"))//是否进行输出到outfile.txt的操作 { this.isout = true; } else { this.isout = false; } if (cmdstr.Contains("-s")) { cmdstr = cmdstr.Replace("-s", ""); this.handleS(cmdstr); } else { for (int i = 0; i < cmdstr.Length; i++)//判断是什么命令 { if (cmdstr[i] == ‘-‘) { if (cmdstr[i + 1] == ‘c‘) { this.handleC(); } else if (cmdstr[i + 1] == ‘w‘) { this.handleW(); } else if (cmdstr[i + 1] == ‘l‘) { this.handleL(); } else if (cmdstr[i + 1] == ‘a‘) { this.handleA(); } } } } } public void handleC()//调用正则表达式对字符数的统计进行审查 { var cStr = this.allstr; Regex re = new Regex(@"(\r\n)|(\S)|(\u0020)|(\u3000)"); //换行和回车符不是同一个 int count = re.Matches(this.allstr).Count; Console.WriteLine(); Console.WriteLine(this.name + " " + "字符数:" + count); this.rstFile(Convert.ToString(this.name + " " + "字符数:" + count)); this.outputFile(Convert.ToString(this.name + " " + "字符数:" + count), this.isout); } public void handleW() { string wStr = this.allstr; string[] sArray = wStr.Split(new char[3] { ‘ ‘, ‘,‘, ‘\r‘ }, StringSplitOptions.RemoveEmptyEntries); //" "与","作为分割符 int count = 0; foreach (string s in sArray)//遍历统计单词数量 { count++; } Console.WriteLine(); Console.WriteLine(this.name + " " + "单词数:" + count); this.rstFile(Convert.ToString(this.name + " " + "单词数:" + count)); this.outputFile(Convert.ToString(this.name + " " + "单词数:" + count), this.isout); } public void handleL() { FileStream fs = new FileStream(@name, FileMode.Open); StreamReader sr = new StreamReader(fs); int lines = 0; while (sr.ReadLine() != null)//遍历统计行数(包含空行) { lines++; } sr.Close(); fs.Close(); Console.WriteLine(this.name + " " + "行数:" + lines); this.rstFile(Convert.ToString(this.name + " " + "行数:" + lines)); this.outputFile(Convert.ToString(this.name + " " + "行数:" + lines), this.isout); } public void handleA()//空行/注释行/代码行的计数 { FileStream fs = new FileStream(@name, FileMode.Open); StreamReader sr = new StreamReader(fs); string lines = ""; int nullcount = 0; int notedcount = 0; int codecount = 0; while ((lines = sr.ReadLine()) != null) { lines = lines.Trim(‘ ‘);//每一行去掉两头空白字符 lines = lines.Trim(‘\t‘);//每一行去掉两头TAB字符 if (lines == "" || lines.Length <= 1) { nullcount++;//空行计数加一 } else if (lines.Length > 2 && (lines.Substring(0, 2) == "//" || lines.Substring(1, 2) == "//")) { notedcount++;//注释行计数加一 } else if (lines.Length == 2 && (lines.Substring(0, 2) == "//")) { notedcount++; //注释行计数加一 } else { codecount++;//代码行计数加一 } } sr.Close(); fs.Close(); string outstr = this.name + " " + "空行/注释行/代码行:" + nullcount.ToString() + "/" + notedcount.ToString() + "/" + codecount.ToString(); Console.WriteLine(); Console.WriteLine(this.name + " " + "空行/注释行/代码行:" + @"{0}/{1}/{2}", nullcount, notedcount, codecount); this.rstFile(outstr); this.outputFile(outstr, this.isout); } public void handleS(string cmd)//-s命令调用其它命令函数 { string rootPath = Directory.GetCurrentDirectory(); string[] files = Directory.GetFiles(rootPath, "*.txt"); foreach (string file in files) { FileStream fs = new FileStream(@file, FileMode.Open); StreamReader sr = new StreamReader(fs); this.allstr = sr.ReadToEnd(); sr.Close(); fs.Close(); this.name = file; this.checkCmd(cmd); } } public void rstFile(string str)//输出函数 { string filePath = Directory.GetCurrentDirectory(); StreamWriter sw = new StreamWriter(@filePath + "//" + "result.txt", true, Encoding.UTF8); sw.WriteLine(str); sw.Close(); } public void outputFile(string str, bool isout)//-0 { if (isout) { string filePath = Directory.GetCurrentDirectory(); StreamWriter sw = new StreamWriter(@filePath + "//" + "output.txt", true, Encoding.UTF8); sw.WriteLine(str); sw.Close(); } } } }
可以发现性能有了明显提升
测试用例及结果:
用例1:
结果:
用例2:
结果:
错误用例示范:
总结与收获
在这次wordCount的设计与测试中,我对于软件测试有了较为详细的认知,在学习过程中,我逐渐掌握了c#文件的读写操作,正则表达式的基本应用,控制台命令的实现,
读写命令的逻辑判断,异常或错误的处理方式的运用,同时掌握了白盒测试,静态测试,性能测试的基本操作,在以后的学习,开发过程中,我也会将在这
次开发过程中学到的东西运用到实际中。
原文:https://www.cnblogs.com/ulysses497/p/9826552.html