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 更好地阅读本文,可点击这里 基本要求 ...
随机推荐
- Python学习之变量的作用域
学习地址:http://www.jianshu.com/p/17a9d8584530 1.变量作用域LEGB 1.1变量的作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空 ...
- TPS和QPS区别
TPS和QPS区别 http://blog.csdn.net/kobejayandy/article/details/9374747
- 新机器连接老机器遇到的ERROR
Ansible无法连接老旧机器 报错内容: [root@BI ansible]# ansible -i /etc/ansible/hosts GameServer -m ping 10.10.113. ...
- 数据分析与处理之二(Leveldb 实现原理)
郑重声明:本篇博客是自己学习 Leveldb 实现原理时参考了郎格科技系列博客整理的,原文地址:http://www.samecity.com/blog/Index.asp?SortID=12,只是为 ...
- 杂项-Java:JCP
ylbtech-杂项-Java:JCP JCP(Java Community Process) 是一个开放的国际组织,主要由Java开发者以及被授权者组成,职能是发展和更新. 1. 中文名:jcp 外 ...
- DNS 解析流程
DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工 ...
- js实现的点击div区域外隐藏div区域
首先看下JS的事件模型,JS事件模型为向上冒泡,如onclick事件在某一DOM元素被触发后,事件将跟随节点向上传播,直到有click事件绑定在某一父节点上,如果没有将直至文档的根. 阻止冒泡:1.对 ...
- class function
type TTest = class public class function sayHello :String; function saybye:String; ...
- Oracle11g-BBED安装
oracle 11g中缺bbed包 下载地址: https://pan.baidu.com/s/19DVvIajarDjnynILNwQDWQ 密码:tmqt 1.BBED的安装 1.上传(sbbdp ...
- Linux字符设备驱动实现
Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进 ...