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