作业:WordCount--实现字符数,单词数,行数的统计
1. Gitee 地址
https://gitee.com/fyxiaobai/wordcount
2. PSP表格
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
30 |
25 |
· Estimate |
· 估计这个任务需要多少时间 |
30 |
25 |
Development |
开发 |
700 |
1000 |
· Analysis |
· 需求分析 (包括学习新技术) |
100 |
120 |
· Design Spec |
· 生成设计文档 |
60 |
80 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
40 |
40 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
80 |
60 |
· Design |
· 具体设计 |
100 |
100 |
· Coding |
· 具体编码 |
210 |
400 |
· Code Review |
· 代码复审 |
60 |
100 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
50 |
100 |
Reporting |
报告 |
100 |
130 |
· Test Report |
· 测试报告 |
50 |
50 |
· Size Measurement |
· 计算工作量 |
30 |
50 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
20 |
30 |
合计 |
830 |
1155 |
3. 需求说明
WordCount的需求可以概括为:对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。
可执行程序命名为:wc.exe,该程序处理用户需求的模式为:
wc.exe [parameter] [input_file_name]
基本功能:
wc.exe -c file.c 对字符数的统计
wc.exe -w file.c 对单词数的统计
wc.exe -l file.c 对行数的统计
wc.exe -o result.txt 将结果输出到指定文件result.txt(文件名可以随意输入,不过文件后缀格式要写成txt)
注意:
空格,水平制表符,换行符,均算字符。
由空格或逗号分割开的都视为单词,不做单词的有效性校验。
-c,-w,-l参数可以共用同一个输入文件。比如:wc.exe -c -w file.c
-o 必须与文件名同时使用,且输出文件必须紧跟在-o参数后面,不允许单独使用-o参数。
老师还为我们介绍了扩展功能和高级功能,由于时间关系,我没有去实现扩展功能和高级功能。
4. 解题思路
采用C语言编写。根据题目的要求,通过命令行参数的形式输入,我就想到了要用main函数的argv参数,然后根据不同的输入来进行相应的模式,对参数要进行识别。关于查询单词数,行数,字符数,通过设置三个全局变量,设计相应的算法进行计数,最后在打印出来并保存到相应的文件中。还有文件的读取,写入,保存文件,这些要采用库函数中的一些方法,这就是我的大体思路。
5. 程序设计实现过程
运用C语言编写,首先对命令行参数进行解析,由函数获取输入的模式。文件名可以自己输入,输入的文件名必须存在,输出的文件名可以自己写,如果未写,就默认输出到result.txt文件中。关于查询字符数,单词数,行数,我写在同一个函数里,通过全局变量进行计数,根据你的命令,来打印出相印的过程。
6. 代码说明
解析命令行参数:
while((opt=getopt(argc,argv,"a:l:w:c:o:")) != -1)
{
switch(opt)
{
//-a 指令显示字符数,单词数,行数
case 'a':
l = w = c = 1;
strcpy(inputFileName,optarg);
break;
//-l 指令显示行数
case 'l':
l = 1;
strcpy(inputFileName,optarg);
break;
//-w 指令显示单词数
case 'w':
w = 1;
strcpy(inputFileName,optarg);
break;
//-c 指令显示字符数
case 'c':
c = 1;
strcpy(inputFileName,optarg);
break;
//-o 用于输出文件
case 'o':
o = 1;
strcpy(outputFileName,optarg);
}
}
统计单词数,字符数,行数:
int countFile(char *filename){
FILE *fp; // 指向文件的指针
char buffer[1000]; //缓冲区,存储读取到的每行的内容
int bufferLength; // 缓冲区中实际存储的内容的长度
int i; // 当前读到缓冲区的第i个字符
char c; // 读取到的字符
int isBlank = 0; // 上个字符是否是空格
int charNumber = 0; // 当前行的字符数
int wordNumber = 0; // 当前行的单词数
if( (fp=fopen(filename, "rb")) == NULL ){
perror(filename);
return -1;
}
// 每次读取一行数据,保存到buffer,每行最多只能有1000个字符
while(fgets(buffer, 1000, fp) != NULL){
bufferLength = strlen(buffer);
// 遍历缓冲区的内容
for(i=0; i<bufferLength; i++){
c = buffer[i];
if( c==' ' || c=='\t'){ // 遇到空格
!isBlank && wordNumber++; // 如果上个字符不是空格,那么单词数加1
isBlank = 1;
}else if(c!='\n'&&c!='\r'){ // 忽略换行符
charNumber++; // 如果既不是换行符也不是空格,字符数加1
isBlank = 0;
}
}
!isBlank && wordNumber++; // 如果最后一个字符不是空格,那么单词数加1
isBlank = 1; // 每次换行重置为1
// 一行结束,计算总字符数、总单词数、总行数
lineCount++; // 总行数
charCount += charNumber; // 总字符数
wordCount += wordNumber; // 总单词数
// 置零,重新统计下一行
charNumber = 0;
wordNumber = 0;
}
fclose(fp);
return 1;
}
保存文件:
int writeOutput(char *outputFile, char *inputFile)
{
FILE *fp = fopen(outputFile,"w");
if (fp == NULL)
return -1;
fprintf(fp, "%s,", inputFile);
if (c)
{
printf("%s,字符数:%d\n",inputFile,charCount);
fprintf(fp, "字符数: %d ", charCount);
}
if (w)
{
printf("%s,单词数:%d\n",inputFile,wordCount);
fprintf(fp, "单词数: %d ", wordCount);
}
if (l)
{
printf("%s,行数:%d\n",inputFile,lineCount);
fprintf(fp, "行数: %d.\n", lineCount);
}
fclose(fp);
}
7. 测试设计过程
在命令行中输入:
wc.exe -l file.c
wc.exe -w file.c
wc.exe -c file.c
wc.exe -c file.c -o read.txt
经测试,上述都能成功实现并得到结果。
8. 未解决的问题
首先只实现了基本的功能,没有实现作业中的扩展功能和高级功能,由于能力和时间的关系。然后关于基本功能中的有种用法没有实现,比如 wc.exe -c -w file.c,这种多个命令的没有实现,只实现了单个命令,我自己在尝试过这方面,可能是自己对于main函数中的argv中的参数的问题有些还不是很清楚,只会弄一个,我经过反复尝试弄出来了一些,但是又出现了其他的问题,可能是哪里弄错了,这是项目过程中的问题。
9. 作业总结
整个作业是运用软件工程的一些方法来进行完成,我以前从来没有这样子来完成作业,自己关于软件工程的理论也不是知道很多,按照老师的要求,通过在PSP中对自己的项目进行估计与实际工作,我感觉这很不一样,很多自己预估的时间和最后完成的时间差距较大,不如在实际编码过程中,我估计的时间远小于写作的时间,这说明在实际问题中,考虑的东西更多了,有了更多自己想弄的东西,当然自己的经验也是还远远不够,我觉得这很重要,对于作业的时间的一个把握有时候可以让我们自己看到自己的成长与积累,以前自己都是想到啥子写啥子,现在更系统的对自己想写的东西进行规划,然后再来实际写作,我觉得这个是种很好的方式,写起来有明确的思路,就是时间可能差距较大,这是我最大的感受。
10. 参考文献链接
https://baike.baidu.com/item/getopt/4705064?fr=aladdin
https://blog.csdn.net/woshiwangbiao/article/details/53379392
https://blog.csdn.net/weixin_42076389/article/details/80111137
https://baike.baidu.com/item/perror
作业:WordCount--实现字符数,单词数,行数的统计的更多相关文章
- 单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
https://github.com/alibaba/p3c/blob/master/阿里巴巴Java开发手册(详尽版).pdf 单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表 ...
- python 脚本(获取指定文件夹、指定文件格式、的代码行数、注释行数)
1.代码的运行结果: 获取 指定文件夹下.指定文件格式 文件的: 总代码行数.总注释行数(需指定注释格式).总空行数: #coding: utf-8 import os, re # 代码所在目录 FI ...
- c - 统计字符串"字母,空格,数字,其他字符"的个数和行数.
#include <stdio.h> #include <ctype.h> using namespace std; /* 题目:输入一行字符,分别统计出其中英文字母.空格.数 ...
- EditText 几种显示方式,固定行数,自适应行数
1.显示7行,超过7行自动向下补充行数 <EditText android:id="@+id/edt_content" android:layout_width=" ...
- C++统计代码注释行数 & 有效代码行数 & 代码注释公共行 & 函数个数
问题来源,在14年的暑假的一次小项目当中遇到了一个这样的问题,要求统计C++代码的注释行数,有效代码行数,代码注释公共行数,以及函数个数. 下面稍微解释一下问题, 1)注释行数:指有注释的行,包括有代 ...
- JS 实现计算一段文字中的字节数,字母数,数字数,行数,汉字数。
看到了匹配,第一个想到了用正则表达式,哈哈,果然很方便.不过正则表达式高深莫测!我还没有研究明白啊..目前学了点皮毛.代码如下: <!DOCTYPE html PUBLIC "-//W ...
- Vim搜索、取消高亮、显示行数、取消行数
1.显示行数 :set nu 2.取消行号 :set nu! 3.高亮搜索 /target 4.取消高亮 :noh
- python3 计算文件夹中所有py文件里面代码行数,注释行数,空行数
import os,re #代码所在位置 FILE_PATH = './' def analyze_code(codefilesource): ''' 打开一个py文件统计其中的代码行数,包括空格和注 ...
- TextView 限制最大行数、最小行数、字数超过“...”表示
最小行数: android:minLines = "2" //最小行数为2 最大行数: android:maxLines = "2" //最大行数为2 文字超过 ...
- 获取apache ignite缓存中的数据行数少于实际行数
我将ignite项目打包放到linux下,在linux下获取window中存放在oracle数据库中的数据,linux服务器作为ignite的服务端节点,我在本地启动tomact,作为ignite客户 ...
随机推荐
- Logback 整合 RabbitMQ 实现统一日志输出
原文地址:Logback 整合 RabbitMQ 实现统一日志输出 博客地址:http://www.extlight.com 一.前言 公司项目做了集群实现请求分流,由于线上或多或少会出现请求失败或系 ...
- 织梦调用文章 ID (来源:百度知道)
问:{dede:field.id /} {dede:channel type='son' orderby='sortrank'} <a href='[field:typeurl/]'>&l ...
- Mybatis常见面试题 二
1.mybatis是什么? (1)mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动.创建连接.创建state ...
- 实际用户ID和有效用户ID (一) *****
在Unix进程中涉及多个用户ID和用户组ID,包括如下: 1.实际用户ID和实际用户组ID:标识我是谁.也就是登录用户的uid和gid,比如我的Linux以simon登录,在Linux运行的所有的命令 ...
- AsyncTask使用详细说明
AsyncTask使用: 在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行.在单线程模型中始终要记住两条法则: 1. 不要 ...
- PREV-1_蓝桥杯_核桃的数量
问题描述 小张是软件项目经理,他带领3个开发组.工期紧,今天都在加班呢.为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑).他的要求是: 1. 各组的核桃数量必须相同 2. 各组内必须能平分核桃( ...
- linux下maven项目clean失败
今天在linux下创建了一个项目自动化发布的脚本,在执行到 mvn clean package -Dmaven.test.skip=true 的时候,项目clean失败 查下下度娘,windows下导 ...
- 排查linux下java应用cpu占用过高
用于快速排查Java的CPU性能问题(top us值过高),自动查出运行的Java进程中消耗CPU多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用.目前只支持Linux.原因是Mac.Win ...
- springMVC学习(9)-全局异常处理
一.异常处理思路: 系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生. 系统的da ...
- [UE4]动态数组:TArray容器
为什么使用UE4提供的容器类? 如果你用过C++的STL库,你就知道STL提供了各种各样的容器/数据结构,使得你对处理很多数据的时候非常快捷高效.UE4同样也提供了类似的库,库里面的类型是以T开头的, ...