wc.exe C++实现
Github项目地址
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 35 |
· Estimate | · 估计这个任务需要多少时间 | 90 | 120 |
Development | 开发 | ||
· Analysis | · 需求分析 (包括学习新技术) | 100 | 140 |
· Design Spec | · 生成设计文档 | 120 | 90 |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | 50 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 25 |
· Design | · 具体设计 | 20 | 55 |
· Coding | · 具体编码 | 300 | 450 |
· Code Review | · 代码复审 | 40 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 100 |
Reporting | 报告 | ||
· Test Report | · 测试报告 | 120 | 150 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 10 |
合计 | 1040 | 1295 |
解题思路
项目工作被分成三个层次:基本、扩展、高级。
应该由最底层的单文件处理出发,延伸到多文件的处理。
由各项的功能如何定义和实现出发,来充实我们的程序。
- -c 统计文件中的字符数
以程序的眼光看待,任何字符(除了‘\r’),均算是一个字符。
基于这样的定义,对目标文件的每读入一个字符,若其不是‘\r’,均增加统计的字符数。 - -w 统计文件中的词的数量
词的定义多种多样,这里的定义采用一系列连续的字母或数字或下划线,为一个词;或者对于中文来说,一个字即为一个词。
基于这样的定义,我们可以把所有键盘上打出的符号视作一个栏杆,栏杆两边的有字符数部分视作是两个独立的词,以此来统计词的数量。 - -l 统计文件中共有几行
行数的判定十分明朗,当程序每读到一个‘\n’时,或文件读完毕时(但是文件有内容时),视作一个换行,如此来统计行数。 - -s 递归处理目录下符合条件的文件
C++的文件处理十分麻烦,我在此处卡了许久。需要利用封装度较低的库函数来实现对文件夹的便利和通配符的支持,还有中文的支持。由此使用了io.h、direct.h、windows.h、getopt,这四个库文件。通过自己手写封装函数来实现自己的需求。 - 返回更复杂的数据(代码行 / 空行 / 注释行)。
相较于上一个而言,这个较为简单和明确:
- 空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
- 代码行:本行包括多于一个字符的代码。
- 注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
设计实现过程
程序设计主要分三个部分,主要逻辑围绕着main展开。
程序包含两个类,其中一个负责全流程的读入解析和输出,另外一个工具类作为中文支持存在,提供字符转换。
工具类 WStringTool中包含有
- string GbkToUtf8(const std::string& strGbk);
- string Utf8ToGbk(const std::string& strUtf8);
- wstring UTF8ToUnicode(const char* str);
- char *UnicodeToUTF8(const wchar_t* str);
- wstring GbkToUnicode(const char* strGbk);
- string UnicodeToGbk (const std::wstring& strUnicode);
六种方法,这里只使用了GbkToUnicode和UTF8ToUnicode这两个方法。
在main()中使用库文件getopt来获取命令行下每一个参数存在性。
while(true)
{
int c = getopt(argc, argv, par);
if(c == -1)
break;
switch (c) {
case 'c':Work::calcChar = true;
break;
case 'w':Work::calcWord = true;
break;
case 'l':Work::calcLine = true;
break;
case 's':recursive = true;
break;
case 'a':Work::detail = true;
break;
case 1: //读入到文件参数
match.push_back(optarg);
default:
break;
}
}
这里的case 1会对每一个文件都进行压入,可以通过此点来拓展出进行处理多文件的能力。
work.cpp中读入文件的操作,权衡了易用性和高效性。
bool Work::readFile(const wchar_t* fileName)
{
ifstream fin;
fin.open(fileName, ios::binary);
if(fin.is_open() == false)
return false;
fin.seekg(0, ios::end);
int len = static_cast<int>(fin.tellg()) + 1;
fin.seekg(0, ios::beg);
delete res;
init();
res = new char[len];
fin.read(res, len);
res[len-1] = '\0'; // before is 0xCD
this->fileName = wstring(fileName);
return true;
}
关于每一行代码的检测函数,集成度较高,解耦难度高,请到我项目地址去查看。
测试运行
运行参数:wc.exe helloworld.txt -c -w -l
运行结果:
...\helloworld.txt
The number of char is 104
The number of word is 15
The number of line is 8
运行参数:wc.exe *.txt -c -w -l
运行结果:
...\helloworld.txt
The number of char is 104
The number of word is 15
The number of line is 8
...\x.txt
The number of char is 5
The number of word is 2
The number of line is 1
运行参数:wc.exe *.txt -s -a
运行结果:
...\helloworld.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 1
...\x.txt
The number of blank-line is 0
The number of code-line is 1
The number of annotation-line is 0
...\kkkk\ssss.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 0
...\kkkk\x.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 0
...\ssss\ssss.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 0
...\ssss\x.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 0
...\kkkk\ssss\ssss.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 0
...\kkkk\ssss\x.txt
The number of blank-line is 0
The number of code-line is 7
The number of annotation-line is 0
程序运行的截图:
之前提及到的处理多文件的能力的拓展
项目小结
这是我个人第一次在编程中使用软件工程的思想,在实践过程中,我发现理论和实践的结合需要多次操作,才能更好的融会贯通,使得理论指导实践,成就一项良好的工程。
项目开始时选定的C++,低估了其掌握的难度,尤其是在文件的遍历和文件编码中踩坑甚多,让我看到了我在语言掌握上的不足,期待今后更加努力。
软件工程的PSP表,第一次使用,对于自己每项任务完成时间的估计没有经验参考,随着直觉估量,导致偏差过大,工程完成预期时间严重拖后,需要进行进一步的学习。
wc.exe C++实现的更多相关文章
- WC.exe【C】
gitee传送门!!!(电脑打不开github,多次尝试未果,决定先用gitee存着先) 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序 ...
- 小白のjava实现wc.exe功能
GitHub地址 项目完成情况 基本功能列表(已实现) wc.exe -c file.c //返回文件 file.c 的字符数 wc.exe -w file.c //返回文件 file. ...
- 模仿WC.exe的功能实现--node.js
Github项目地址:https://github.com/102derLinmenmin/myWc WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要 ...
- wc.exe
1 /* 2 * 没能实现的功能:wc.exe -s递归处理目录下符合条件的文件 3 * wc.exe -x 显示图形界面 4 * 5 * 6 * 实现的功能: wc.exe -c显示文件的字符数. ...
- 软工作业1—java实现wc.exe
github项目地址 https://github.com/liyizhu/wc.exe WC 项目要求 基本功能列表: wc.exe -c file.c //返回文件 file.c 的字符数 ...
- 用c语言基本实现wc.exe功能
网址:https://github.com/3216005214/wc.exe wc项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿 ...
- java实现wc.exe
Github地址:https://github.com/ztz1998/wc/tree/master 项目相关要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功 ...
- (第三周)wc.exe—命令行实现对指定目录下文件的操作
一.用户需求 程序处理用户需求的模式为: wc.exe [parameter][filename] 在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下: 1.基本功能 支持 -c ...
- 软工作业No.1。Java实现WC.exe
网址:https://github.com/a249970271/WC WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有w ...
- 软件工程 wc.exe 代码统计作业
软件工程 wc.exe 代码统计作业分享 1. Github 项目地址 https://github.com/EdwardLiu-Aurora/WordCount 更好地阅读本文,可点击这里 基本要求 ...
随机推荐
- 一次在局域网中ssh连接的尝试
最近到手一台二手HP笔记本.卖我本子的是以为很漂亮的服装设计师,她因为有了一台新的Mac本所以HP本就闲置了,于是就卖给了我.本子性能跟我自己的三星本差不多,除了电池不太给力,每次开机都会提示601. ...
- saas服务提供商
这段时间接触了不少行业的东西,这里谈几点肤浅的看法.从市场行情上讲,SaaS风口还在,不过热度明显向大数据.物联网.人工智能.区块链等转移. 做得比较好的有这些SaaS提供商,每个领域的都有那么几家的 ...
- Shell脚本基础知识详细介绍(一)
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁.Shell既是一种命令语言,又是一种程序设计语言.作为命令语言,它交互式地解释和执行用户输入的命令:作为程序设计语言,它定义了各种 ...
- Eclipse 中 No java virtual machine was found... 解决方法
这个链接说的不错,http://www.mafutian.net/123.html,,但是还有一种可能是64位和32位的问题,也就是eclipse32位只能用32位的jdk,eclipse64位的只能 ...
- ALUA and SRM
A couple important (ALUA and SRM) notes There’s some internal dialog today on our “VMware Champions” ...
- Object-C 多线程中锁的使用-NSLock
在多线程的编程环境中,锁的使用必不可少! 于是,今天来总结一下为共享资源加锁的操作方法. 一.使用synchronized方式 //线程1 dispatch_async(dispatch_ge ...
- mysql replication /mysql 主从复制原理
一下内容均是根据leader的培训分享整理而成 ************************************我是分割线*********************************** ...
- ejs的简单应用
获取数据 var init = function(){ api.my_bean_list({ },function(datas){ console.log(datas); if (datas.errn ...
- 使用Docker模拟ansible集群环境
/etc/ansible/hosts 192.168.99.100 ansible_ssh_port=8081 ansible_ssh_user=root 配置容器免密码SSH登录
- jQueryUI Sortable 应用Demo
最近工作用需要设计一个自由布局的页面设计.我选了jQuery UI 的 sortable ,可以拖拽,自由排序 使用很方便,写一个demo,做个记录. 第一.单项目自由排序 下图效果 代码段: < ...