文件wordcount的实现思路
文件wordcount的实现思路
论用c语言的简单实现
(我先辈就算被钉在棺材里也绝对不会去下ide写java的)
真痛苦,文件夹遍历写不出来,凉了
Github地址:点我进入
我的真实博客:开启吧,伟大航路!可能,也许,应该,需要一个梯子(淦)
1.PSP
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
60 |
90 |
· Estimate |
· 估计这个任务需要多少时间 |
180 |
360 |
Development |
开发 |
150 |
240 |
· Analysis |
· 需求分析 (包括学习新技术) |
30 |
90 |
· Design Spec |
· 生成设计文档 |
0 |
0 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
0 |
0 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
30 |
30 |
· Design |
· 具体设计 |
60 |
60 |
· Coding |
· 具体编码 |
120 |
240 |
· Code Review |
· 代码复审 |
30 |
90 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
30 |
60 |
Reporting |
报告 |
10 |
10 |
· Test Report |
· 测试报告 |
0 |
0 |
· Size Measurement |
· 计算工作量 |
0 |
0 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
0 |
0 |
合计 |
2.程序设计思路
程序包含三个大类,分为Main,Count,File
Main:程序的主函数类,实现整个程序的所有功能的调用,实现要执行功能的判断、各种统计功能的调用和最后的信息输出的功能,其中含有以下方法:
main():作为主函数。
int getopt(int argc,char * const argv[],const char * optstring):命令分析函数,对终端中传入的参数进行判断,统计需要执行的功能;
void output(char filename[100]):对结果进行打印
Count:此类为本工程的主体,完成了-c, -w, -l, -o, -a, -e这些功能的实现,其中含有以下方法:
void charactercount(char filename[100]):统计文件中的字符数;
void wordcount(char filename[100]):统计文件的单词数;
void linecount(char filename[100]):统计文件的行数;
void allcounter(char filename[100]):统计文件的代码行、空行和注释行的行数;
void stoplistcount(char filename[100]):统计文件中除去停用词表中的停用词后,剩余的单词总数;
File:此类实现了递归处理目录下符合条件的文件,其中含有以下方法:
void diropen(File dir):递归处理dir目录下的所有文件,对以.c结尾的文件进行命令行中的操作;
3.文件的读取操作与wordcount的实现
有关文本文件与二进制文件
文本文件与二进制文件的区别并不是物理上的,而是逻辑上的。这两者只是在编码层次上有差异。简单来说,文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码等等。二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思.
从上面可以看出文本文件基本上是定长编码的(也有非定长的编码如UTF-8)。而二进制文件可看成是变长编码的,因为是值编码嘛,多少个比特代表一个值,完全由你决定。大家可能对BMP文件比较熟悉,就拿它举例子吧,其头部是较为固定长度的文件头信息,前2字节用来记录文件为BMP格式,接下来的8个字节用来记录文件长度,再接下来的4字节用来记录bmp文件头的长度。
C的文本方读写与二进制读写的差别仅仅体现在回车换行符的处理上.文本方式写时,每遇到一个''\n''(0AH换行符),它将其换成''\r \n''(0D0AH,回车换行),然后再写入文件;当文本读取时,它每遇到一个''\r\n''将其反变化为''\n'',然后送到读缓冲区.二进制读写时,其不存在任何转换,直接将写缓冲区中数据写入文件.总地来说,从编程的角度来说,C中文本或二进制读写都是缓冲区与文件中二进制流的交互,只是文本读写时有回车换行的转换.所以当写缓冲区中无换行符''\n''(0AH),文本写与二进制写的结果是一样的,同理,当文件中不存在''\r\n''(0DH0AH)时,文本读与二进制读的结果一样.
文件读取操作
对文件的读和写是最常用的文件操作。在C语言中提供了多种文件读写的函数:
字符读写函数 :fgetc和fputc
字符串读写函数:fgets和fputs
数据块读写函数:freed和fwrite
格式化读写函数:fscanf和fprinf
wordcount的基本实现
简单的来说,wordcount其实是通过判定文件内空格和回车(转义字符)的数量
来进行的,
核心代码如下:
if (ch != ' ' && ch != '\n')//读取字符不是空格和换行,则字符数增加
{
++charcount;
}
if (ch == ' ' || ch == '\n')//读取字符是空格或换行则单词数增加
{
++wordcount;
}
}
if (charcount > 0)//特殊情况下单词计数的设置
{
++wordcount;
}
if (ch == '\n')
{
++linecount;
}
}
if (charcount > 0)
{
++linecount;
}
对于特定词组数量的统计实际上是把所需要统计的词组放入数组进行比对,ban词表同理.本次作业真正的难点还是一个命令行多选项共参的实现和引发的附属问题
.(我编程太菜被编译器吊打了)
多个命令行参数识别的实现
使用getopt()
函数进行参数分析,原型如下:
#include<unistd.h>
int getopt(int argc,char * const argv[],const char * optstring);
具体使用用例如下(参考):
#include <stdio.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int ch;
//opterr = 0;//将opterr设置为0,这样就可以在getopt()函数发现错误的时候强制它不输出任何消息。
while((ch = getopt(argc,argv,"a:bcde"))!= -1)
{
switch(ch)
{
case 'a':
{
printf("option a:’%s’\n",optarg);
break;
}
case 'b':
{
printf("option b :b\n");
break;
}
case '?'//当命令行输入参数无效或者没有输入时,且opterr没有设定为0时,会打印以下信息
{
printf("argument error\n");
break;
}
default:
;
}
}
return 0;
}
更新:好吧,函数很美好,现实很残酷,用了些奇计淫巧才成功让多个带参选项共用一个参数,具体见代码,就不贴了,重点注意一个optind
的变化
4.测试设计过程
测试中本着用例覆盖所有分支的目的进行设计
测试用例如下所示:
!@#$%^&*()_+{}|"?><[]\;',./~`a //测试-c字符统计功能
!@#$%^ &*()_+{}|"?><[]\;',.
/~`a
File write, name = new File(outputPath);//下面测试-w和-l的单词统计功能
writename.createNe | wFile();
Buffe, redWriter out = new BufferedWrit, er(new FileWriter(writename));
out.close();
//代码行测试
if(){
} else if(){
} else{
}
//注释行测试
s//
//
//
5.测试用例
终端输入:
//单选项测试
wc.exe -l file.c
wc.exe -c file.c
wc.exe -w file.c
wc.exe -a file.c
wc.exe -o out.txt
//多选项测试
wc.exe -l -c file.c
wc.exe -l -w file.c
wc.exe -l -a file.c
wc.exe -c -w file.c
wc.exe -c -a file.c
wc.exe -w -a file.c
//多选项带ban词表测试(必定失败,禁词表未完成)
wc.exe -l -w file.c -e stop.txt
wc.exe -c -w file.c -e stop.txt
wc.exe -w -a file.c -e stop.txt
wc.exe -l -c -w -a file.c -e stop.txt
wc.exe -l -c -w -a file.c -e stop.txt -o out.txt
wc.exe -l -c -w -a -s *.c -e stop.txt
wc.exe -l -c -w -a -s *.c -e stop.txt -o out.txt
//错误测试
//无读取的文件
wc.exe -l -c
wc.exe -l -w
wc.exe -l -a
wc.exe -c -w
wc.exe -c -a
wc.exe -w -a
//有-e,但无停用词表文件名
wc.exe -l -w file.c -e
wc.exe -c -w file.c -e
wc.exe -w -a file.c -e
//有-o,但无输出文件名
wc.exe -l -c -w -a file.c -e stop.txt -o
wc.exe -l -c -w -a -s *.c -e stop.txt -o
//有-s,但无"*.c"(必定失败,遍历未完成)
wc.exe -l -c -w -a -s -e stop.txt
wc.exe -l -c -w -a -s -e stop.txt -o out.t
参考引用: