一、首先 附上Github项目地址:https://github.com/June1104/WordCountjava
二、psp表格git
PSP2.1表格github
PSP2.1函数 |
PSP阶段学习 |
预估耗时测试 (分钟)编码 |
实际耗时spa (分钟).net |
Planning命令行 |
计划 |
||
· Estimate |
· 估计这个任务须要多少时间 |
1000 | 1200 |
Development |
开发 |
||
· Analysis |
· 需求分析 (包括学习新技术) |
100 | 150 |
· Design Spec |
· 生成设计文档 |
30 | 50 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 | 20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
10 | 20 |
· Design |
· 具体设计 |
100 | 120 |
· Coding |
· 具体编码 |
500 | 700 |
· Code Review |
· 代码复审 |
50 | 60 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
80 | 100 |
Reporting |
报告 |
||
· Test Report |
· 测试报告 |
60 | 60 |
· Size Measurement |
· 计算工做量 |
20 | 25 |
· Postmortem & Process Improvement Plan |
· 过后总结, 并提出过程改进计划 |
20 | 20 |
三、思路大概就是开始先想着代码功能,总结一下功能就是读取文件,而后得到文件的字符数,单词数,行数,以及扩展功能读取当前目录和子目录下的文件,而后再返回更复杂的数据(代码行 / 空行 / 注释行)等。由于本身对java语言彻底不熟悉,只是在大二学面向对象的时候应付做业用过,相对来讲可能还c熟悉一点(但其实掌握的也很差),因此相比之下就选择了c,但其实做业作起来仍是蛮吃力的,想要什么做用,就要百度各类不一样的函数,好比打开文件的fopen函数,好比在识别命令行时的字符串比较函数strcmp等等。说到识别命令,那又是在写代码时遇到的一个大问题,在cmd里输入的不一样命令,怎么与代码链接起来呢。后来百度到了“主函数main中变量(int argc,char *argv[])的含义”,看懂这个知识点后感受开始有点上手,因而慢慢的弄懂了这个问题。而后说回来,在读取字符数、单词数这些问题上,先是本身想了,须要判断什么条件,而后在百度的帮助下,完善思路,能够正确的运行获取结果。
四、程序实现过程大概就是从各类百度中开始学习,开始上手。代码主要分红了三个部分,把不一样的功能写在了三个文件里,分别是主函数main.c、获取字符数单词数行数的功能wc.c和获取文件的代码函数file.c。主函数里引用wc.c和file.c,主函数的主要流程就是判断cmd命令,而后读取文件,再根据wc.c函数判断不一样条件,获得结果。
五、代码说明
a、在int main(int argc, char **argv)函数中,根据命令中的.c格式和.txt格式初步判断是要获取的文件仍是输出结果到哪一个文件。argv[]指向命令行的参数,当遍历到.c格式时,就把该参数赋值为文件路径,以遍接下来获取;当遍历到.txt格式时,就把该参数赋值为文件名。不然,输出error。
for(i = 1; i < argc; ++i)/*argc是命令行总的参数个数*/ { p = argv[i]; while(*++p != NULL); if(strcmp(p - 2, ".c") == 0) { path = argv[i]; end = i; } if(strcmp(p - 4, ".txt") == 0) { if(strcmp(argv[i - 1], "-o") == 0) filename = argv[i]; else { printf("error.\n"); return EXIT_FAILURE; } } }
b、在file.c文件中的读取文件函数,返回buf首地址,fopen函数此时打开文件,形式为只读“r”。把文件里读到的内容放到缓冲中,最后返回缓冲首地址(此段功能的代码为网上搜索得到),在wc.c中用这个首地址++来判断各类不一样条件。
char *readfile(char *path)/*返回buf首地址 参数是文件路径*/ { FILE *fp ; int len; char *buf; if ((fp = fopen(path, "r") )== NULL) { printf("open file %s error.\n", path); exit(0); } len = filelength(fp); buf = (char *) malloc (len); fread(buf, sizeof(char), len, fp); fclose(fp); *(buf + len - 1) = '\0'; return buf; }
c、wc.c代码中的主要函数就是统计文件中的字符数,单词数和行数
这里是基本判断
int isalpha(char a){ if ((a <= 'z'&&a>='a') || (a<='Z'&&a>='A')) return 1; return 0; }/*判断是不是单词*/ int isspace(char c){ if ((' ' == c) || ('\n' == c) || ('\t' == c) || (',' == c) || (';' == c) || (')' == c) || ('(' == c) || ('{' == c) || ('}' == c)) return 1; return 0; }/*判断是不是分隔符*/
下面是计算字符数,单词数,行数的方法。以参数buf遍历,指针加一,字符数就加一;当碰见换行符时,行数加一;当是单词且经过一个间隔符后,单词数加一。
while( (c = *buf++) != '\0') { ++info->nc; if('\n' == c) ++info->nl; if(isspace(c)) state = OUT; else if(isalpha(c) && OUT == state) { state = IN; ++info->nw; } }
六、测试设计过程,对不一样的功能,分别进行不一样的测试,而后进行组合命令再测试不一样的功能。
a、测试用例设计以下
不一样输入 |
结果 |
wc.exe -c test.c |
test.c, 字符数:1386 |
wc.exe -w test.c |
test.c, 单词数:131 |
wc.exe -l test.c |
test.c, 行数:59 |
wc.exe -l -w test.c |
test.c, 行数:59 test.c, 单词数:131 |
wc.exe -c test.c -o res.txt |
![]() |
wc.exe -c -w -l test.c |
test.c, 字符数:1386 test.c, 单词数:131 test.c, 行数:59 |
wc.exe -c -w -l test.c -o resl.txt |
![]() |
wc.exe -c -w -l test1.c |
test1.c, 字符数:111 |
wc.exe -c -w -l test1.c -o res2.txt |
![]() |
wc.exe -c test2.c |
open file test2.c error. |
(备注,同一目录下放了test.c和test.c1文件,没有test.c2文件)
b、测试脚本文件为test.bat,脚本中测试内容有
start wc.exe wc.exe -l test.c
start wc.exe wc.exe -w test.c
start wc.exe wc.exe -c test.c
wc.exe -l -w test.c
wc.exe -c test.c -o output.txt
wc.exe -c -w -l test.c
wc.exe -c -w -l test.c -o outputl.txt
wc.exe -c -w -l test1.c
wc.exe -c -w -l test1.c -o output2.txt
wc.exe -c test2.c
在cmd中运行test.bat 结果为:
文件目录截图
cmd截图
输出txt文件截图:
七、参考文献连接
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/
http://www.jb51.net/article/107168.htm
https://baike.baidu.com/item/c%E8%AF%AD%E8%A8%80fopen%E5%87%BD%E6%95%B0/1775995?fr=aladdin
https://baike.baidu.com/item/strcmp/5495571?fr=aladdin