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. Long Jumps(二分查找lower_bound()函数的运用)

    Valery is a PE teacher at a school in Berland. Soon the students are going to take a test in long ju ...

  2. LeetCode Judge Route Circle

    原题链接在这里:https://leetcode.com/problems/judge-route-circle/description/ 题目: Initially, there is a Robo ...

  3. C#:使用UPnP来穿透NAT使内网接口对外网可见

    在写完Object 672后,软件的一个致命问题暴露出来,如果服务器和客户端都在内网环境下,即双方都通过NAT来接触外网,那么此时客户端是无法直接和服务器交流的. 解决方案可以是: 1:把服务器部署在 ...

  4. FastAdmin 推荐 Git 在线学习教程

    FastAdmin 推荐 Git 在线学习教程 因为 FastAdmin 推荐使用 Git 管理代码,有很多小伙伴对 Git 不是很熟悉. 也苦于找不到好的教程,我就分享一个 Git 在线学习教程. ...

  5. 程序员转项目管理之考证PMP

    转行项目经历是IT人的出路之一,最近身边有好几个同事都在备考PMP,从个人未来职业发展来看,如果你有将来转行项目管理的想法,应该去尝试考一下PMP. PMP(Project Management Pr ...

  6. Sqoop--Free-form Query Imports 自由查询模式下$CONDITIONS关键字的作用

    Scoop是用来实现HDFS文件系统和关系型数据库如MySQL之间数据传输和转换的工具. 从MySQL导出到HDFS可以通过--table, --columns and --where等设置数据抽出的 ...

  7. linux下的时间

    1.linux下时间管理机制: 在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现.为了保持系统时间与CMOS时间的一致性,Linux每隔11分钟会 ...

  8. 数据格式化和ModelAttribute注解的介绍

    关于数据传递: 客户端传递数据到服务端: 1.使用普通的形式 A.传递简单的数据 如果是说你传递的数据的名称跟控制层中的形参的名称不一致的情况下需要使用 注解: @RequestParam()如果存在 ...

  9. ES之二:Elasticsearch原理

    Elasticsearch是最近两年异军突起的一个兼有搜索引擎和NoSQL数据库功能的开源系统,基于Java/Lucene构建.最近研究了一下,感觉 Elasticsearch 的架构以及其开源的生态 ...

  10. 【转】火狐浏览器中firebug插件的时间线域解释

      又到了上图时间了..对照这张图,各个时间所对应的意义就很简单明了.   阻挡(Blocking):每个浏览器有并发连接数量的上限(例如Firefox对每个host限制6个连接),如果当前建立的连接 ...