个人项目
WordCount(C语言)
GITHUB地址:https://github.com/wen328328/WordCount
一、题目描述
- 实现一个简单而完整的软件工具(源程序特征统计程序)。实现下列功能:
-
基础功能:
-
1.字符数的统计(-C)
-
2.单词数的统计(-W)
-
3.行数的统计(-L)
-
拓展功能:
-
1.特殊行的统计(-A)其中包括:代码行、注释行、空行。
-
2.递归遍历文件(-S)
-
高级功能:
-
1.界面功能
-
- 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
- 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
二、PSP表格
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
30 |
30 |
· Estimate |
· 估计这个任务需要多少时间 |
705 |
860 |
Development |
开发 |
600 |
750 |
· Analysis |
· 需求分析 (包括学习新技术) |
90 |
120 |
· Design Spec |
· 生成设计文档 |
20 |
30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 |
30 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
30 |
40 |
· Design |
· 具体设计 |
300 |
360 |
· Coding |
· 具体编码 |
60 |
60 |
· Code Review |
· 代码复审 |
20 |
20 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
60 |
90 |
Reporting |
报告 |
75 |
80 |
· Test Report |
· 测试报告 |
40 |
30 |
· Size Measurement |
· 计算工作量 |
20 |
30 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
15 |
20 |
合计 |
705 |
860 |
三、思路
1.刚开始看到个人项目时,脑袋是懵的。因为自身基础差,所以对于这类个人的项目也是第一次做,没有经验,并且也没有相关知识。所以选择了唯一懂得一些基础知识的C语言来完成这项项目。
2.在刚开始的时候,首先上网搜索相关成品进行参考,并且学习其中的函数用法以及模块的算法,然后去搜集相关资料进行学习,并且以网上的为模板,尝试去编写,并且在编写出来并且成功编译后将代码仔细看一遍,再进行改进。
3.在刚开始编写时,调用函数模块进行编程但是未能成功,所以干脆将之写于一个主函数,不作模块生成及调用。
四、设计实现过程
- 根据输入将程序分为4种功能:三个基础功能以及一个扩展功能(特殊行的统计)。
- 分为四个模块,主函数打开文件随后,根据输入进行对应检索。
- 其中特殊行的统计一块分为三部分:空行,注释行,代码行。
五、关键代码及注释
变量设置及文件的打开
char* s = (char*)malloc(256 * sizeof(char));//字符串用以逐行读取文件
int b = 0, c = 0, d = 0, e = 0; int code = 0, blank = 0, exp = 0, num = 0, word = 0; char a; char t; FILE* stream;//设置文件指针 errno_t err;//设置ERRNO_T类型变量 if (err = fopen_s(&stream, "D:\\test.txt", "r") != 0)//读取对应文件,此处为D盘下TEST.TXT文件 { printf("error\n");//文件不存在,读取失败 }
字符数的统计
while ((a = fgetc(stream) )!= EOF)//逐个读取文件中的字符至文件结尾 { if ((a != ' ') && (a != '\n') && (a != '\t'))//判定字符 { num++;//判定成功,加一 } } fclose(stream);//关闭该指针所指向文件
printf("字符数:%d\n", num);//输出
单词数的统计
while ((a = fgetc(stream)) != EOF)//同上 { if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z')) { if (word == 0)//单词判定,加一后,该单词不再重复判定,直至非字母字符置零WORD { num ++; word = 1; } } else { word = 0; } } fclose(stream); printf("单词数:%d\n", num);
行数的统计
while (fgets(s, 256, stream) != NULL)//逐行读取文件 { num++;//每读取一行,加一 } free(s);//释放指针 fclose(stream); printf("行数:%d\n", num);
特殊行的统计
while (fgets(s, 256, stream) != NULL) { for (int i = 0; *(s + i) != '\0'; i++)//逐个读取行中的字符 { if ((*(s + i) == '/' && *(s + i + 1) == '/') && b == 0 && c == 0)//判定是否为注释行 { exp++, b = 1;//若是,则加1,并且该行若有其他“//”也不做加数 } else { c = 1;//判定开头是否为“//” } if (((*(s + i) <= 'z' && *(s + i) >= 'a') || (*(s + i) <= 'Z' && *(s + i) >= 'A') )&& b == 0 && d == 0) { code++, d = 1;//判定是否为代码行,若不为注释行,且不再重复判定,加一 } } b = 0, c = 0, d = 0;//重置系数,进入下一行 num++;//统计行数 } free(s); fclose(stream); blank = num - code - exp;//总行数-代码行-注释行(我只分了三种特殊行,空行及前面提及的代码行和注释行) printf("空白行:%d\n注释行:%d\n代码行:%d", blank, exp, code);//输出
六、测试运行
七、总结
- 在这次的作业中,受益匪浅,无论是对于编译器的使用方面,还是在C语言的学习方面,而最大的收获莫过于对于学习方法的领悟。大学里,靠的最多的还是自觉,但要从众多人中脱颖而出,学习方法固然重要。这次作业中对于自己的学习方法已经有了大致的方向,并且也明白了编程语言要靠自己去查阅相关知识,理解并且运用。
- 在此次作业中,明白了自身的不足,知识不完备,而且对于已有知识的运用也是粗心大意,就好比在做字符数的统计时,错把WHILE当做IF用法,这个小错误,找了我几个小时。(看着编译窗口:诶,怎么不运行,好黑好黑,是不是编译器坏了啊)为此还卸载了重下。
- 下一次争取调用函数完成项目,毕竟不调用函数就相当于白学了。
- 这里还想吐槽一下,编译器的更新换代,有些函数不被运用,只能用新版本的函数,这一点感触很深。在不了解函数用法的同时,还要去搜集新一代的函数参数要求,太难了T-T.