GitHub地址:https://github.com/dachai9/personal-project.git
1. WC 项目要求
  • 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 返回更复杂的数据(代码行 / 空行 / 注释行)。 --完成 (空行的格式控制字符只识别%d)

    • 空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
    • 代码行:本行包括多于一个字符的代码。
    • 注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:

      } //注释:在这种情况下,这一行属于注释行。
  • 高级功能:

    -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。 --未完成

需求举例:

  wc.exe -s -a .c

返回当前目录及子目录中所有
.c 文件的代码行数、空行数、注释行数。

2. PSP表格
PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 10
· Estimate · 估计这个任务需要多少时间 20 10
Development 开发 540 985
· Analysis · 需求分析 (包括学习新技术) 20 20
· Design Spec · 生成设计文档 20 5
· Design Review · 设计复审 (和同事审核设计文档) 5 20
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 15 20
· Design · 具体设计 80 80
· Coding · 具体编码 240 300
· Code Review · 代码复审 60 300
· Test · 测试(自我测试,修改代码,提交修改) 120 240
Reporting 报告 100 180
· Test Report · 测试报告 60 80
· Size Measurement · 计算工作量 10 40
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 60
合计 660 1175
3. 解题思路
  • 需求分析:

    • 基础:需要进行文件操作,fgetc,fopen,fclose;
    • 扩展:_finddata_t handle,符号判断;
  • c语言,文件操作方法;
  • wc.exe [parameter][file_name]主函数参数;
4. 设计实现过程:
5. 代码说明
  • 主函数:
int main(int argc, char *argv[]) {
printf("传入参数:%d\n", argc);
char para;//需求
char fpara[] = "";
char *func;//-需求
//判断输入多少需求
int k=0;
for(k=1; k<=argc; k++) {
func = argv[k];
if(func[0] != '-') {
break;
}
}
printf("\nk: %d\n", k);
char *add = argv[k]; for(int j=k; j<argc; j++) {
add = argv[j];
for(int i=1; i<k; i++) {
func = argv[i];
para = func[1]; switch(para) {
case 's':
printf("\n");
recursion(add);
break;
case 'a':
justify(add);
break;
case 'l':
countLines(add);
break;
case 'w':
countWords(add);
break;
case 'c':
countChars(add);
break;
default:
break;
}
}
}
}
  • 行数统计
int countLines(char *fileName) {
FILE *fp;
fp = fopen(fileName, "r");
char ch;
int cl = 0; if(fp == NULL) {
printf("打开文件失败!\n");
} else {
ch = fgetc(fp);
if(ch == EOF) {
printf("行数:0\n");
return 0;
}
while(ch != EOF) {
if(ch != '\n') {
ch = fgetc(fp);
} else {
cl++;
ch = fgetc(fp);
}
}
printf("行数:%d\n", ++cl);
} fclose(fp);
return cl;
}
  • 单词数统计
int countWords(char *fileName) {
FILE *fp;
fp = fopen(fileName, "r");
char ch;
int cw = 0;
int word = 0; if(fp == NULL) {
printf("打开文件失败!\n");
} else {
ch = fgetc(fp);
if(ch == EOF) {
printf("单词数:0\n");
return 0;
}
while(ch != EOF) {
/*if(ch != ' ' && ch != '\n') {
//putchar(ch);
ch = fgetc(fp);
}else {
cw++;
//printf("单词数:%d\n", cw);
ch = fgetc(fp);
}*/
if((ch == ' ' || ch == '\n') && word == 1) {
word = 0;
cw+=1;
} else if(((ch >= 'a' && ch <= 'z') || ch >= 'A' && ch <='Z') && word == 0) {
word = 1;
}
//printf("%c", ch);
ch = fgetc(fp);
}
if(word == 1) cw++;
printf("单词数:%d\n", cw);
} fclose(fp);
return cw;
}
  • 字符数统计
int countChars(char *fileName) {
FILE *fp;
fp = fopen(fileName, "r");
int cc = 0;
char ch; if(fp != NULL) {
ch = fgetc(fp);
while(ch != EOF) {
if(ch != '\n') {
cc++;
ch = fgetc(fp);
} else {
ch = fgetc(fp);
}
}
printf("字数:%d\n", cc);
} else {
printf("打开文件失败!\n");
} fclose(fp);
return cc;
}
  • 遍历文件(函数本身可处理.c,但由于传入参数如果是.c,代表一个一个文件传入,所以这里函数作用不明显)
int recursion(char *fpara) {
long handle;//用于查找的句柄
struct _finddata_t fileinfo;//文件信息的结构体
handle = _findfirst(fpara, &fileinfo);
if(-1 == handle) {
printf("查找失败!");
system("pause");
return -1;
}
printf("%s\n", fileinfo.name);
while(!_findnext(handle, &fileinfo)) {
printf("%s\n", fileinfo.name);
}
_findclose(handle);
return 0;
}
  • 特殊行判断(其中的zs_f 是判断是否出现/*)
int justify(char *fileName) {
FILE *fp;
fp = fopen(fileName, "r");
if(NULL == fp) {
printf("打开文件失败!");
system("pause");
return 0;
}
int zs_f = 0;
char ch_fp, ch_next;//ch_next:下一个字符
int k=0, d=0, z=0, f=0;//k: 空行 d:代码行 z:注释行 f:是否顶格
ch_fp = fgetc(fp);
ch_next = fgetc(fp);
while(ch_fp != EOF) {
if(ch_fp == ' ' || ch_fp == '}' || ch_fp == '{') {
ch_fp = ch_next;
ch_next = fgetc(fp);
} else {
if((ch_fp == '\n') && f == 0) {
k++;
} else if(ch_fp == '/' && ch_next == '/' && f == 0) {
z++;
} else if(ch_fp == '/' && ch_next == '*' && f == 0) {
z++;
zs_f = 1;
}
if(zs_f == 1) {
while(ch_fp != '*' || ch_next != '/') {
if(ch_fp == '\n') {
z++;
}
ch_fp = ch_next;
ch_next = fgetc(fp);
}
zs_f = 0;
} ch_fp = ch_next;
ch_next = fgetc(fp);
if(ch_fp == '{' || ch_fp == '}') {
ch_fp = ch_next;
ch_next = fgetc(fp);
}
if(f == 0) {
f = 1;
if(ch_next == ' ') {
f = 0;
}
}
if(f == 2) {
if(ch_fp == '\n') {
k++;
}
f=0;
}
if(ch_fp == '\n') {
f = 2;
if(ch_next == '\n')
f=0;
if(ch_next == EOF)
k++;
}
}
}
d = countLines(fileName) - k - z;
printf("\n空格行:%d\n代码行:%d\n注释行:%d\n", k, d, z); printf("文档结束!\n");
return 0;
}
测试运行
  • 基础部分:

  • 扩展部分:

  • 错误参数:

    文件路径输入错误

    无操作输入

项目小结

对GitHub的使用还不熟练;学了新的知识:_finddata_t;提高了逻辑思维能力(特殊行判断);学会控制情绪。

花了这么长时间,说到底还是太菜,没有好好理清思路就上手,所以做好设计文档还是蛮重要的。

非常喜欢PSP,觉得这个计划表可以能鞭策自己再加努力,不管是对项目需求的分析分解还是对自己编程能力的提高。

还有就是自己预计的时间跟最终的时间相差了将近8小时!!!太夸张了。还是要充分了解需求才能好好估算时间。

最新文章

  1. Linux C语言解析并显示.bmp格式图片
  2. CSS3 background-size 属性
  3. 做网站用UTF-8编码还是GB2312编码?
  4. 从idea上通过路径去导入项目
  5. 移动开发之浅析cocos2d-x的中文支持问题
  6. mysql绿色版在windows系统中的启动
  7. IOS 创建App的最佳捷径
  8. FPGA中改善时序性能的方法_advanced FPGA design
  9. Codeforces 385B Bear and Strings
  10. Postman Mock Server
  11. Kubernetes — 重新认识Docker容器
  12. Android使用ViewPager+PhotoView实现图片查看器
  13. Flink - ResultPartition
  14. javascript中的值如何传递到django下的views.py中或者数据库中?
  15. PHP操作mongoDB 笔记
  16. oracle逐步学习总结之权限和角色(基础六)
  17. Java编程的逻辑 (44) - 剖析TreeSet
  18. hdu-1130(卡特兰数+大数乘法,除法模板)
  19. 一款基于jquery滑动后固定于顶部的导航
  20. ThinkPHP自定义错误页面、成功页面及异常页面

热门文章

  1. Bug -- WebService报错(两个类具有相同的 XML 类型名称 &quot;{http://webService.com/}getPriceResponse&quot;。请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。)
  2. mongo安装和cmd运行命令
  3. Zuul token FIlter 验证失败结果输出
  4. Skill 解决 Design Library 被识别成 Technology Library 的问题
  5. 7.12 NOI模拟赛 探险队 期望 博弈 dp 最坏情况下最优策略 可并堆
  6. Centos7 如何通过win10 的远程桌面连接进行远程访问
  7. SeaweedFS在.net core下的实践方案(续一)
  8. Mybais面试题(一)
  9. UIPickView的简单使用
  10. Spring Security学习笔记一