(1)github链接
(2)PSP表格:
PSP阶段 | 预估耗时(小时) | 实际耗时(小时) |
计划: | ||
估计这个任务需要多少时间 | 17 | 18 |
开发: | ||
需求分析(包括学习新技术) | 1 | 0.5 |
生成设计文档 | 1 | 0.5 |
设计复审(和同事复审设计文档) | 0.5 | 0.5 |
代码规范(为目前的开发制定合适的规范) | 0.5 | 0.5 |
具体设计 | 0.5 | 2 |
具体编码 | 7.5 | 8 |
代码复审 | 1 | 1 |
测设(自我测试,修改代码,提交修改) | 2 | 2 |
报告: | ||
测试报告 | 1 | 1 |
计算工作量 | 1 | 1 |
事后总结,并提出过程改进计划 | 1 | 1 |
合计 | 17 | 18 |
(3)
基本功能
*1 wc.exe -c file.c //返回文件 file.c 的字符数
*2 wc.exe -w file.c //返回文件 file.c 的单词总数
*3 wc.exe -l file.c //返回文件 file.c 的总行数
*4 wc.exe -o outputFile.txt //将结果输出到指定文件outputFile.txt
扩展功能
*1 wc.exe -s //递归处理目录下符合条件的文件
*2 wc.exe -a file.c //返回更复杂的数据(代码行 / 空行 / 注释行)
*3 wc.exe -e stopList.txt // 停用词表,统计文件单词总数时,不统计该表中的单词
刚拿到题目后,我并没有很着急的立马动手写程序,而是先进行了需求分析,认真的理解了基本功能和扩展功能的需求,预估了整个项目的耗时,填写PSP文档,思考了下整体的架构。然后就分功能开始写函数。
分函数实现每个功能:
//统计字符数
public int charCounts(File f) throws Exception{
String str;
int charCount = 0;
BufferedReader br=new BufferedReader(new FileReader(f));//当前工程目录下
while((str=br.readLine())!=null){
charCount += str.length();
}
File fs=new File("result.txt");
FileWriter fw = new FileWriter(fs, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(f.getName()+",字符数: "+charCount);
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
return charCount;
}
//统计单词数
public int wordCounts(File f) throws Exception{
String str;
int wordCount = 0;
BufferedReader br=new BufferedReader(new FileReader(f));
while((str=br.readLine())!=null){
wordCount += str.split(",| ").length;
}
File fs=new File("result.txt");
FileWriter fw = new FileWriter(fs, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(f.getName()+",单词数: "+wordCount);
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
return wordCount;
}
//统计总行数
public int lineCounts(File f) throws Exception{
String str;
int lineCount = 0;
BufferedReader br=new BufferedReader(new FileReader(f));
while((str=br.readLine())!=null){
lineCount++;
}
File fs=new File("result.txt");
FileWriter fw = new FileWriter(fs, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(f.getName()+",总行数: "+lineCount);
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
return lineCount;
}
//递归处理目录下符合条件的文件
public ArrayList<File> recursion(String filedir) throws Exception{
//ArrayList<File> listFiles=new ArrayList<File>();
File file=new File(filedir);
File []files=file.listFiles();
if(files==null)return null;
for(File f:files){
if(f.isFile()){
if(f.getName().endsWith(".c")){
fileList.add(f);
}
}else if(f.isDirectory()){
recursion(f.getAbsolutePath());
}
}
return fileList;
}
//代码行,空行,注释行
public void complex(File f) throws Exception{
String str;
boolean nodeflag = false;
int codeLine = 0;
int spaceLine = 0;
int nodeLine = 0;
BufferedReader br =new BufferedReader(new FileReader(f));
while((str=br.readLine())!=null){
if(str.matches("\s*/\*.*")&&str.matches(".*\*/\s*")){
nodeLine++;
continue;
}
else if(str.matches("\s*|}\s*|\{\s*")){
spaceLine++;
}
else if(str.matches("//.*")){
nodeLine++;
}else if(str.matches("\s*/\*.*")){
nodeLine++;
nodeflag = true;
}else if(str.matches(".*\*/\s*")){
nodeLine++;
nodeflag = false;
}else if(nodeflag)nodeLine++;
else codeLine++;
}
File fs=new File("result.txt");
FileWriter fw = new FileWriter(fs, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(f.getName()+",代码行/空行/注释行: "+codeLine+"/"+spaceLine+"/"+nodeLine);
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
}
//停用词表
public void stopWords(File f) throws Exception{
String str;
int wordCount=0;
int stopWord=0;
BufferedReader br=new BufferedReader(new FileReader(f));
while((str=br.readLine())!=null){
String []line= str.split(",| ");
wordCount+=line.length;
for(int i=0;i<line.length;i++){
if(line[i].equals("while"))stopWord++;
if(line[i].equals("if"))stopWord++;
if(line[i].equals("switch"))stopWord++;
}
}
int count =wordCount-stopWord;
File fs=new File("result.txt");
FileWriter fw = new FileWriter(fs, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(f.getName()+",单词数: "+count);
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
}
主函数传参后提取参数进行判断,分别调用功能函数:
//main函数
public static void main(String args[]) throws Exception {
Chance zhj=new Chance();
int n= args.length;
boolean sj = false;
boolean ej = false;
String filename=null;
String outputname= args[n-1];
for(int i=0; i<args.length; i++){
if(args[i].equals("-s")){
sj= true;
}
if(args[i].equals("-e")){
ej= true;
}
}//判断是否递归获取当前目录下的文件,和是否使用停用词表
for(int i=0; i<args.length; i++){
if(args[i].endsWith(".c")){
filename=args[i];
}
}
File g = new File(filename);
//记录操作目标文件
if(sj){
zhj.fileList=zhj.recursion(".");//当前工程目录
for(int i=0; i<args.length; i++){
if(args[i].equals("-a")){
for(File f:zhj.fileList){
zhj.complex(f);
}
}
if(args[i].equals("-l")){
for(File f:zhj.fileList){
zhj.lineCounts(f);
}
}
if(args[i].equals("-c")){
for(File f:zhj.fileList){
zhj.charCounts(f);
}
}
if(args[i].equals("-w")){
if(ej){
for(File f:zhj.fileList){
zhj.stopWords(f);
}
}else{
for(File f:zhj.fileList){
zhj.wordCounts(f);
}
}
}
if(args[i].equals("-o")){
String str;
File fs=new File(outputname);
FileWriter fw=new FileWriter(fs,true);
PrintWriter pw=new PrintWriter(fw);
//读取result.txt文件
BufferedReader br =new BufferedReader(new FileReader("result.txt"));
while((str=br.readLine())!=null){
//将数据复制到output.txt文件中
pw.println(str);
}
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
}
}
}
if(!sj){
for(int i=0; i<args.length; i++){
if(args[i].equals("-a")){
zhj.complex(g);
}
if(args[i].equals("-c")){
zhj.charCounts(g);
}
if(args[i].equals("-w")){
if(ej){
zhj.stopWords(g);
}else{
zhj.wordCounts(g);
}
}
if(args[i].equals("-l")){
zhj.lineCounts(g);
}
if(args[i].equals("-o")){
String str;
File fs=new File(outputname);
FileWriter fw=new FileWriter(fs,true);
PrintWriter pw=new PrintWriter(fw);
//读取result.txt文件
BufferedReader br =new BufferedReader(new FileReader("result.txt"));
while((str=br.readLine())!=null){
//将数据复制到output.txt文件中
pw.println(str);
}
pw.flush();//flush实际上就是将所有的写入的流,一次性输出到文件中,之后进行关闭即可。如果没关闭流,也没进行flush,此时的内容并未写入到文件的。
fw.flush();
pw.close();
fw.close();
}
}
}
}
利用exe4j将jar包转换成exe文件,通过控制台调用exe文件并对其传参:
输入文件:
输出结果:
测试用例脚本:
import java.io.*;
import java.util.*;
public class Chance{
public static void main(String args[]) throws Exception{
String []cmd= {" -l file.c"," -c file.c"," -w file.c"," -a file.c"," -l file.c -o output.txt",
" -s -l -w *.c -e stop.txt -o output.txt"," -s -a -c -w *.c -e stop.txt -o output.txt",
" -c -w -l file.c"," -s -a *.c -e stop.txt"," -c -w -l -a file.c"
};//测试用例
for(int i=0; i<cmd.length; i++){
Process p=Runtime.getRuntime().exec("wc.exe"+cmd[i]);
}
}
}
参考文献:
http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html
https://www.cnblogs.com/fnlingnzb-learner/p/6010165.html
http://blog.csdn.net/tianmaxingkong_/article/details/45649343
http://blog.csdn.net/u013549582/article/details/46500395