github地址

https://github.com/lzwk/WordCount

PSP表格

PSP2.1

PSP阶段

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

20

40

· Estimate

· 估计这个任务需要多少时间

20

30

Development

开发

600

900

· Analysis

· 需求分析 (包括学习新技术)

100

150

· Design Spec

· 生成设计文档

20

30

· Design Review

· 设计复审 (和同事审核设计文档)

60

70

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

10

20

· Design

· 具体设计

50

55

· Coding

· 具体编码

500

600

· Code Review

· 代码复审

150

200

· Test

· 测试(自我测试,修改代码,提交修改)

200

200

Reporting

报告

100

120

· Test Report

· 测试报告

40

50

· Size Measurement

· 计算工作量

20

30

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

20

30

 

合计

1910

2525

解题思路

利用控制台执行exe文件,同时传入main()函数的形参,根据传入的形参的不同执行相应的功能,如:字符数、单词数、行数等,不同的输入搭配可以实现不同的高级功能。

程序设计实现过程

本项目采用C语言实现,除main函数外,还有多个自定义函数,其中两个最主要的函数为count()和none(),count()用来统计单词数、行数、注释行数,none()用来统计空行数。

main()函数根据传入的形参的不同,完成不同的输出。其余自定义行数比较简单,下面代码说明中会以isNewline()函数为例进行解释。

代码说明

count()函数用以统计单词数、行数、注释行数,函数中有单词判断,没检测出一个单词word_num+1;每遇到一个'\n',line_num+1;没有到注释行,note_num+1,如果是/*note*/注释,在主是内部没出现一次‘\n’,note_num+1。

int count()//统计单词数、行数、注释行数
{
get();
clearToken();
while (isSpace(ch) || isNewline(ch) || isTab(ch) || isComma(ch))
{
if (isNewline(ch)) line_num++;
get();
}
if (isStar(ch))
{
catToken(ch);
}
else if (isDivi(ch))
{
catToken(ch);
get();
if (isStar(ch))
{
note_num++;
catToken(ch);
do
{
do
{
get();
if (isNewline(ch))
{
note_num++;
line_num++;
} } while (!isStar(ch));
do
{
get();
if (isNewline(ch))
{
note_num++;
line_num++;
}
if (isDivi(ch))
{
catToken(ch);
return ;
}
} while (isStar(ch));
} while (!isStar(ch));
}
if (isDivi(ch))
{
catToken(ch);
do
{
get();
} while (!isNewline(ch));
note_num++;
}
if (isNewline(ch))
line_num++;
}
else if (isEnd(ch))
return ;
else
{
while (!(isSpace(ch) || isNewline(ch) || isTab(ch) || isComma(ch) || isDivi(ch)))
{
catToken(ch);
get();
}
retract();
if(strcmp(stopWord, "") == || strcmp(token,stopWord)!=)
word_num++;
}
return ;
}

以isNewline()为例,解释简单自定义函数:

bool isNewline(char a)
{
if (a == '\n')
return true;
return false;
}

none()函数,根据两个‘\n’中是否小于或等于一个字符来判断是否为空行,满足条件则none_num+1:

void none()//统计空行数
{
int i,j = ;
for (i = ;; i++)
{
if (art[i] == EOF)
break;
if (art[i] != '\n'&& art[i] != '\t'&& art[i] != ' ')
{
j++;
}
if (art[i] == '\n')
{
if (j <= )
none_num++;
j = ;
}
}
}

main()函数,由于功能是逐步添加的,加上自己的代码习惯有待提高,导致main()函数被修改的过于冗杂。重要思想:利用数组flag[7],每一个元素对应一个功能(包括字符数、单词数输出等),为1时表示对应功能执行,反之不执行。

int main(char argc, char* argv[])
{ if (argc<)
printf("请在控制台输入正确命令!\n");
else
{
if (strcmp(argv[], "wc.exe") != )
printf("可执行文件名输入错误!\n");
else
{
for (int i = ; i<argc; i++)
{
if (strcmp(argv[i], "-c") == )
{
flag[] = ;
}
else if (strcmp(argv[i], "-w") == )
{
flag[] = ;
}
else if (strcmp(argv[i], "-l") == )
{
flag[] = ;
}
else if (strcmp(argv[i], "-o") == )
{
flag[] = ;
}
else if (strcmp(argv[i], "-s") == )
{
flag[] = ;
}
else if (strcmp(argv[i], "-a") == )
{
flag[] = ;
}
else if (strcmp(argv[i], "-e") == )
{
flag[] = ;
}
}
}
} if (flag[] == )
{
_finddata_t sFind;
long lResult = ;
lResult = _findfirst("*.c", &sFind);
if (lResult == -) {
printf("没有找到文件。");
return ;
} int i=,len;
do {
len = strlen(sFind.name);
strcpy_s(filesName[i], len + , sFind.name);//将所有读到的保存到filesname
file_num++;
i++;
} while (_findnext(lResult, &sFind) != -); for (int j = ; j < file_num; j++)
{
fopen_s(&fp, filesName[j], "r");
if (fp == NULL)
printf("error!\n");
int i = ;
do//获取文件内容
{
ch = fgetc(fp);
art[i++] = ch;
} while (ch != EOF);
fclose(fp);
char_num = i; if (flag[] == )//获取停用词
{
fopen_s(&fp, "stopList.txt", "a");
fgets(stopWord, , fp);
fclose(fp);
}
do//核心统计
{
count();
} while (!isEnd(ch));
none(); if (flag[] == )
printf("%s,字符数: %d \n", filesName[j], char_num);
if (flag[] == )
printf("%s,单词数: %d \n", filesName[j], word_num);
if (flag[] == )
printf("%s,总行数: %d \n", filesName[j], line_num);
if (flag[] == )
{
fopen_s(&fp, argv[argc - ], "a");
if (flag[] == )
fprintf(fp, "%s,字符数: %d \n", filesName[j], char_num);
if (flag[] == )
fprintf(fp,"%s,单词数: %d \n", filesName[j], word_num);
if (flag[] == )
fprintf(fp,"%s,总行数: %d \n", filesName[j], line_num);
if (flag[] == )
fprintf(fp, "%s,代码行/空行/注释行: %d/%d/%d \n", filesName[j], line_num - note_num - none_num, none_num, note_num);
fclose(fp);
}
if (flag[] == )
printf("%s,代码行/空行/注释行: %d/%d/%d \n", filesName[j], line_num - note_num - none_num, none_num, note_num);
strcpy_s(stopWord,,"");
for (int i = ; i < ; i++)
art[i] = '\0';
sta = art;
char_num = ;
word_num = ;
line_num = ;
note_num = ;
none_num = ;
}
} else
{
fopen_s(&fp, "file.c", "r");
if (fp == NULL)
printf("error!\n");
int i = ;
do
{
ch = fgetc(fp);
art[i++] = ch;
} while (ch != EOF);
fclose(fp);
char_num = i; if (flag[] == )
{
fopen_s(&fp, "stopList.txt", "r");
fgets(stopWord, , fp);
fclose(fp);
}
do
{
count();
} while (!isEnd(ch));
none(); if (flag[] == )
printf("file.c,字符数: %d \n", char_num);
if (flag[] == )
printf("file.c,单词数: %d \n", word_num);
if (flag[] == )
printf("file.c,总行数: %d \n", line_num);
if (flag[] == )
{
fopen_s(&fp, argv[argc - ], "w");
if (flag[] == )
fprintf(fp, "file.c,字符数: %d \n", char_num);
if (flag[] == )
fprintf(fp, "file.c,单词数: %d \n", word_num);
if (flag[] == )
fprintf(fp, "file.c,总行数: %d \n", line_num);
if (flag[] == )
fprintf(fp, "file.c,代码行/空行/注释行: %d/%d/%d \n", line_num - note_num - none_num, none_num, note_num);
fclose(fp);
}
if (flag[] == )
printf("file.c,代码行/空行/注释行: %d/%d/%d \n", line_num - note_num - none_num, none_num, note_num);
}
printf("\n");
system("pause");
return ;
}

测试设计过程

利用“wc.bat”脚本程序,批量处理,测试用例如下:

测试结果如下:

测试用例中,利用“-o”功能将输出写入文件,其中与“-s”功能同时实现时,写入文件是不会首先清空文件;不与“-s”功能同时实现时,写入文件时会首先清空文件。

可编辑wc.bat来改变测试输入。

参考文献

1.https://www.cnblogs.com/saolv/p/7793379.html

2.https://www.cnblogs.com/chengxs/p/5309215.html

第二周个人作业:WordCount的更多相关文章

  1. 第二周个人作业WordCount

    1.Github地址 https://github.com/JingzheWu/WordCount 2.PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning ...

  2. java第二周的作业

    package java第二周学习; import javax.swing.JOptionPane; public class 数学题 { private int a; private int b; ...

  3. 软件测试第二周个人作业:WordCount

    github地址:https:/github.com/muzhailong/wc.git 第一次写博客很不容易,也算是一个好的开始吧. 1.   个人作业要求 作业简述:根据WordCount的需求描 ...

  4. 第二次结对作业-WordCount进阶需求

    原博客 队友博客 github项目地址 目录 具体分工 需求分析 PSP表格 解题思路描述与设计实现说明 爬虫使用 代码组织与内部实现设计(类图) 算法的关键与关键实现部分流程图 附加题设计与展示 设 ...

  5. Coursera-AndrewNg(吴恩达)机器学习笔记——第二周编程作业

    一.准备工作 从网站上将编程作业要求下载解压后,在Octave中使用cd命令将搜索目录移动到编程作业所在目录,然后使用ls命令检查是否移动正确.如: 提交作业:提交时候需要使用自己的登录邮箱和提交令牌 ...

  6. Coursera-AndrewNg(吴恩达)机器学习笔记——第二周编程作业(线性回归)

    一.准备工作 从网站上将编程作业要求下载解压后,在Octave中使用cd命令将搜索目录移动到编程作业所在目录,然后使用ls命令检查是否移动正确.如: 提交作业:提交时候需要使用自己的登录邮箱和提交令牌 ...

  7. JAVA学习第二周课后作业

    Java 的基本运行单位是类.类由数据成员和函数成员组成.变量之间可以相互转换.String是一个类.static是静态.全局的意思.经过测试,Java的枚举类型定义的Size与String一样都不是 ...

  8. 16级第二周寒假作业H题

    快速幂(三) TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%I64d Problem Description 计算( AB ...

  9. 16级第二周寒假作业E题

    Home_W的位运算4 TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%I64d Problem Description 给 ...

随机推荐

  1. 还是畅通工程(peime算法最小生成树)

    个人心得:就是最小生成树的运用,还是要理解好每次都是从已搭建好的生成树里面选择与她的补集中最短距离,所以那个book数组的更新 需要好生体会.不过还是有缺陷,算法的复杂度为O(n^2),看介绍说用优先 ...

  2. C#获取路由器外网IP,MAC地址

    C#实现的获取路由器MAC地址,路由器外网地址.对于要获取路由器MAC地址,一定需要知道路由器web管理系统的用户名和密码.至于获取路由器的外网IP地址,可以不需要知道路由器web管理系统的用户名和密 ...

  3. angular +H5 上传图片 与预览图片

    //index.html <form class="form-horizontal"> <div class="panel panel-default& ...

  4. C的随想

    c用的是操作系统函数,这个一下子就限制了APi的数量,通过组合这些系统api即可实现功能. c开发的人一般都会熟记系统函数,然后需要确定函数参数的时候,通过man指令进行查看 对于32位64位将会导致 ...

  5. Azure VNet介绍

    Azure VNet的介绍 VNet是Azure云中逻辑隔离的虚拟网络.它包含两个含义: Azure的用户可以在VNet中创建自己的各种资源,感觉想自己的数据中心中一样; 在一个VNet中创建的资源和 ...

  6. oracle的自增长

    mysql的自增长非常容易,一个 AUTO_INCREMENT 就搞定,可是oracle就不行了 下面是oracle的自增长 #创建一个表CREATE TABLE T_TEST_DEPARTMENTS ...

  7. Redis事务和watch

    redis的事务 严格意义来讲,redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的. redis中的事务定义 Redis中的事务(transaction)是一组命令的集合. 事务同 ...

  8. 转:InnoDB Page Structure(InnoDB页面结构详解)

    InnoDB Page Structure(InnoDB页面结构详解) 此转载自登博的博客,给大家分享.

  9. HAproxy+Mycat

    haproxy+mycat搭建haproxy server 10.0.1.134mycat server 10.0.1.134,10.0.1.135mysql master 10.0.1.134mys ...

  10. WINDOWS 7下的记事本程序目录

    这是win7的目录    系统所在分区:\Windows\system32\notepad.exe