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 更好地阅读本文,可点击这里 基本要求 ...
随机推荐
- Qt开发环境下载和安装
Qt是跨平台的图形开发库,目前由Digia全资子公司 Qt Company 独立运营,官方网址: http://www.qt.io/ 也可以访问Qt项目域名:http://qt-project.org ...
- 使用阿里云服务器(OOS)实现图片上传
一: 页面 <%@ page language="java" contentType="text/html; charset=utf-8" pageEnc ...
- java冒泡排序算法例子
总结:运行显示数组下标越界说明,数组长度a.length.表示数组的长度,但索引值是要减一的.勿忘 package com.c2; //冒泡排序 //从小到大的顺序排列 public class MA ...
- Java-Maven-Runoob:Maven 自动化构建
ylbtech-Java-Maven-Runoob:Maven 自动化构建 1.返回顶部 1. 自动化构建定义了这样一种场景: 在一个项目成功构建完成后,其相关的依赖工程即开始构建,这样可以保证其依赖 ...
- Java-API-Package:java.sql百科
ylbtech-Java-API-Package:java.sql百科 提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API.此 API 包括一个框架,凭借 ...
- 1136 A Delayed Palindrome
题意:略. 思路:大整数相加,回文数判断.对首次输入的数也要判断其是否是回文数,故这里用do...while,而不用while. 代码: #include <iostream> #incl ...
- 6.solr学习速成之multicore查询
查询关联多个core 再新建一个core 向每个core添加索引,修改 final static String SOLR_URL = "http://localhost:8080/solr/ ...
- Flask之部署
5.3 部署 当我们执行下面的hello.py时,使用的flask自带的服务器,完成了web服务的启动.在生产环境中,flask自带的服务器,无法满足性能要求,我们这里采用Gunicorn做wsgi容 ...
- php SqlServer 中文汉字乱码
php SqlServer 中文汉字乱码,用iconv函数转换 查询显示的时候,从GB转换为UTF8 <?php echo iconv('GB2312','UTF-8',$row['Name'] ...
- 从cocos2d-x-2.x到cocos2d-x-3.x: lua项目配置
cocos2dx-x3.0的正式版出来也有一段时间了,现在最新的版本是到了3.2alpha,和2.x系列相比,能够找到的相关资料除了官网上的wiki,其他的也不见得多,遇到的一些和2.x的差异和问题在 ...