WC.exe(C语言实现)
github传送门:
项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:程序处理用户需求的模式为:wc.exe [parameter] [file_name]
基本功能列表:
wc.exe -c file.c //返回文件 file.c 的字符数 (实现)
wc.exe -w file.c //返回文件 file.c 的词的数目 (实现)
wc.exe -l file.c //返回文件 file.c 的行数 (实现)
扩展功能:
-s 递归处理目录下符合条件的文件(实现) -a 返回更复杂的数据 (未实现)PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | 1340 | 1280 |
· Analysis | · 需求分析 (包括学习新技术) | 300 | 500 |
· Design Spec | · 生成设计文档 | 40 | 50 |
· Design Review | · 设计复审 (和同事审核设计文档) | 40 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 600 | 500 |
· Code Review | · 代码复审 | 60 | 50 |
· Test | · 测试(自我测试,修改代码,提交修改) | 180 | 50 |
Reporting | 报告 | 110 | 120 |
· Test Report | · 测试报告 | 60 | 60 |
· Size Measurement | · 计算工作量 | 20 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 |
| 1510 | 1460 |
解题思路
拿到题目后首先考虑的是用什么编写,由于我只会JAVA和C,因此给我的选项也不多,最后考虑到C的基础比较扎实,就选择了用C语言来实现。看完项目要求后,自然就会想到通过主函数调用几个功能函数来实现相关要求。
设计实现过程
功能函数分别是字符数统计,词数统计,行数统计以及处理目录下符合条件的文件,最后再通过主函数调用实现其功能,其中词数统计中调用了字符数统计函数,主要用于判断文件中有无字符,有字符则开始统计词数,无字符则直接输出0。
代码说明
头文件
#include "stdio.h"#include "string.h"#include "stdlib.h"#include "io.h"
字符统计
int charcalculate(char *file) /*字符统计*/{ int c=0; FILE *fp; char a; fp=fopen(file,"r"); while(!feof(fp)) { a=fgetc(fp); if(a!=' '&&a!='\n'&&a!='\t') c++; } fclose(fp); c--; return c;}
词数统计:这里调用了charcalculate,主要用于判断文件是否为空,若为空则不需要进行词数统计,若不为空则开始统计词数
int wordcalculate(char *file) /*词数统计*/{ int w=0; FILE *fp; char a; fp=fopen(file,"r"); if (charcalculate(file)==0) w=0; else { while(!feof(fp)) { a=fgetc(fp); if(a==' '||a=='\n'||a=='\t') w++; } w++; } fclose(fp); return w;}
行数统计
int linecalculate(char *file) /*行数统计*/{ int l=0; FILE *fp; fp=fopen(file,"r"); char a; while(!feof(fp)) { a=fgetc(fp); if(a=='\n'||a=='\t') l++; } l++; fclose(fp); return l;}
处理目录下符合条件的文件
int searchfile(void) /*寻找目录下txt文件*/{ //文件存储信息结构体 struct _finddata_t fileinfo; //保存文件句柄 long fHandle; //文件数记录器 int t=0; if( (fHandle=_findfirst( "F:\\Microsoft Visual Studio\\MyProjects\\WordCount\\Debug\\*txt", &fileinfo )) == -1L ) { printf( "当前目录下没有txt文件\n"); } else do{ t++; printf("找到文件:%s\n", fileinfo.name); }while (_findnext(fHandle,&fileinfo)==0); _findclose(fHandle); printf("txt文件数量:%d\n",t); return 0;}
主函数
int main (int argc, char *argv[]) /*主函数*/{ if(!strcmp(argv[1],"-c")) { printf("charnumber:%d\n",charcalculate(argv[2])); } else if(!strcmp(argv[1],"-w")) { printf("wordnumber:%d\n",wordcalculate(argv[2])); } else if (!strcmp(argv[1],"-l")) { printf("linenumber:%d\n",linecalculate(argv[2])); } else if(!strcmp(argv[1],"-s")) { searchfile(); } return 0;}
测试运行
测试文件与测试文件夹
程序运行结果
项目小结
在完成项目的过程中遇到了一些困难,比如从未写过命令行程序的我在看到题目后是一头雾水,后来在百度的帮助下,我得知了只需要在main函数中添加argc和argv两个参数就能通过命令行运行程序,其中argc是命令行输入参数的个数,argv存储了所有的命令行参数。其次,我也通过翻阅书籍了解到处理文件的相关函数,如fopen,fgetc等等。关于处理文件夹下符合条件的文件这一块,我手上的书本没有详细的介绍,在网上查找到相关信息后才学会使用_finddata_t获取文件夹内所有文件。不过比较可惜的是最终还是没有实现统计更为复杂数据以及设计用户图形界面的功能,相关的内容就在这次项目提交后再去学习了解吧。