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. 代码说明
  • 主函数:
  1. int main(int argc, char *argv[]) {
  2. printf("传入参数:%d\n", argc);
  3. char para;//需求
  4. char fpara[] = "";
  5. char *func;//-需求
  6. //判断输入多少需求
  7. int k=0;
  8. for(k=1; k<=argc; k++) {
  9. func = argv[k];
  10. if(func[0] != '-') {
  11. break;
  12. }
  13. }
  14. printf("\nk: %d\n", k);
  15. char *add = argv[k];
  16. for(int j=k; j<argc; j++) {
  17. add = argv[j];
  18. for(int i=1; i<k; i++) {
  19. func = argv[i];
  20. para = func[1];
  21. switch(para) {
  22. case 's':
  23. printf("\n");
  24. recursion(add);
  25. break;
  26. case 'a':
  27. justify(add);
  28. break;
  29. case 'l':
  30. countLines(add);
  31. break;
  32. case 'w':
  33. countWords(add);
  34. break;
  35. case 'c':
  36. countChars(add);
  37. break;
  38. default:
  39. break;
  40. }
  41. }
  42. }
  43. }
  • 行数统计
  1. int countLines(char *fileName) {
  2. FILE *fp;
  3. fp = fopen(fileName, "r");
  4. char ch;
  5. int cl = 0;
  6. if(fp == NULL) {
  7. printf("打开文件失败!\n");
  8. } else {
  9. ch = fgetc(fp);
  10. if(ch == EOF) {
  11. printf("行数:0\n");
  12. return 0;
  13. }
  14. while(ch != EOF) {
  15. if(ch != '\n') {
  16. ch = fgetc(fp);
  17. } else {
  18. cl++;
  19. ch = fgetc(fp);
  20. }
  21. }
  22. printf("行数:%d\n", ++cl);
  23. }
  24. fclose(fp);
  25. return cl;
  26. }
  • 单词数统计
  1. int countWords(char *fileName) {
  2. FILE *fp;
  3. fp = fopen(fileName, "r");
  4. char ch;
  5. int cw = 0;
  6. int word = 0;
  7. if(fp == NULL) {
  8. printf("打开文件失败!\n");
  9. } else {
  10. ch = fgetc(fp);
  11. if(ch == EOF) {
  12. printf("单词数:0\n");
  13. return 0;
  14. }
  15. while(ch != EOF) {
  16. /*if(ch != ' ' && ch != '\n') {
  17. //putchar(ch);
  18. ch = fgetc(fp);
  19. }else {
  20. cw++;
  21. //printf("单词数:%d\n", cw);
  22. ch = fgetc(fp);
  23. }*/
  24. if((ch == ' ' || ch == '\n') && word == 1) {
  25. word = 0;
  26. cw+=1;
  27. } else if(((ch >= 'a' && ch <= 'z') || ch >= 'A' && ch <='Z') && word == 0) {
  28. word = 1;
  29. }
  30. //printf("%c", ch);
  31. ch = fgetc(fp);
  32. }
  33. if(word == 1) cw++;
  34. printf("单词数:%d\n", cw);
  35. }
  36. fclose(fp);
  37. return cw;
  38. }
  • 字符数统计
  1. int countChars(char *fileName) {
  2. FILE *fp;
  3. fp = fopen(fileName, "r");
  4. int cc = 0;
  5. char ch;
  6. if(fp != NULL) {
  7. ch = fgetc(fp);
  8. while(ch != EOF) {
  9. if(ch != '\n') {
  10. cc++;
  11. ch = fgetc(fp);
  12. } else {
  13. ch = fgetc(fp);
  14. }
  15. }
  16. printf("字数:%d\n", cc);
  17. } else {
  18. printf("打开文件失败!\n");
  19. }
  20. fclose(fp);
  21. return cc;
  22. }
  • 遍历文件(函数本身可处理.c,但由于传入参数如果是.c,代表一个一个文件传入,所以这里函数作用不明显)
  1. int recursion(char *fpara) {
  2. long handle;//用于查找的句柄
  3. struct _finddata_t fileinfo;//文件信息的结构体
  4. handle = _findfirst(fpara, &fileinfo);
  5. if(-1 == handle) {
  6. printf("查找失败!");
  7. system("pause");
  8. return -1;
  9. }
  10. printf("%s\n", fileinfo.name);
  11. while(!_findnext(handle, &fileinfo)) {
  12. printf("%s\n", fileinfo.name);
  13. }
  14. _findclose(handle);
  15. return 0;
  16. }
  • 特殊行判断(其中的zs_f 是判断是否出现/*)
  1. int justify(char *fileName) {
  2. FILE *fp;
  3. fp = fopen(fileName, "r");
  4. if(NULL == fp) {
  5. printf("打开文件失败!");
  6. system("pause");
  7. return 0;
  8. }
  9. int zs_f = 0;
  10. char ch_fp, ch_next;//ch_next:下一个字符
  11. int k=0, d=0, z=0, f=0;//k: 空行 d:代码行 z:注释行 f:是否顶格
  12. ch_fp = fgetc(fp);
  13. ch_next = fgetc(fp);
  14. while(ch_fp != EOF) {
  15. if(ch_fp == ' ' || ch_fp == '}' || ch_fp == '{') {
  16. ch_fp = ch_next;
  17. ch_next = fgetc(fp);
  18. } else {
  19. if((ch_fp == '\n') && f == 0) {
  20. k++;
  21. } else if(ch_fp == '/' && ch_next == '/' && f == 0) {
  22. z++;
  23. } else if(ch_fp == '/' && ch_next == '*' && f == 0) {
  24. z++;
  25. zs_f = 1;
  26. }
  27. if(zs_f == 1) {
  28. while(ch_fp != '*' || ch_next != '/') {
  29. if(ch_fp == '\n') {
  30. z++;
  31. }
  32. ch_fp = ch_next;
  33. ch_next = fgetc(fp);
  34. }
  35. zs_f = 0;
  36. }
  37. ch_fp = ch_next;
  38. ch_next = fgetc(fp);
  39. if(ch_fp == '{' || ch_fp == '}') {
  40. ch_fp = ch_next;
  41. ch_next = fgetc(fp);
  42. }
  43. if(f == 0) {
  44. f = 1;
  45. if(ch_next == ' ') {
  46. f = 0;
  47. }
  48. }
  49. if(f == 2) {
  50. if(ch_fp == '\n') {
  51. k++;
  52. }
  53. f=0;
  54. }
  55. if(ch_fp == '\n') {
  56. f = 2;
  57. if(ch_next == '\n')
  58. f=0;
  59. if(ch_next == EOF)
  60. k++;
  61. }
  62. }
  63. }
  64. d = countLines(fileName) - k - z;
  65. printf("\n空格行:%d\n代码行:%d\n注释行:%d\n", k, d, z);
  66. printf("文档结束!\n");
  67. return 0;
  68. }
测试运行
  • 基础部分:

  • 扩展部分:

  • 错误参数:

    文件路径输入错误

    无操作输入

项目小结

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

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

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

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

个人项目(C语言)的更多相关文章

  1. 结对编程项目——C语言实现WordCount Web化

    结对编程项目 代码地址 201631062219,201631011410 gitee项目地址:https://gitee.com/xxlznb/pair_programming 作业地址:https ...

  2. github上传的项目代码语言类型修改

    我们在访问gitHub的时候,经常会看到如下的语言标记,那么这个是如何设置的呢,下面我就整理下具体的操作步骤: 首先在项目根目录下创建一个文件,文件名为.gitattributes 文件内容为: *. ...

  3. github 修改项目默认语言

    我们在提交到github上的项目有时候被识别成了其它的语言,非我们使用的语言,这个时候可以采取以下措施来强制将语言改成我们需要的语言 在项目中创建一个文件 .gitattributes 打开.gita ...

  4. github修改仓库项目的语言类型

    github是 采用Linguist来自动识别你的代码应该归为哪一类. 解决方法: 我们可以在仓库的根目录下添加.gitattributes文件: ## 使用 `.gitattributes` 配置文 ...

  5. 【ruby项目,语言提交检查(一)】怎样高速学习ruby ?

    怎样高速学习ruby ? 学习语言最快的思路. 变量,常量,变量类型,操作符. 逻辑语句如 if, else, switch, for, foreach, do while, break, 等等.要学 ...

  6. 在大型项目上,Python 是个烂语言吗

    Robert Love, Google Software Engineer and Manager on Web Search. Upvoted by Kah Seng Tay, I was the ...

  7. TIA Portal V13 WinCC中创建多语言项目

    1. 在项目树下选择“语言和资源”,双击打开“项目语言”,设置编辑语言和参考语言. 2. 在项目语言栏中勾选项目所需要的多种语言,我们以选择德语.英语和中文为例 3. 点击“参考语言”,切换语言为英语 ...

  8. C语言编程学习:写的秒速计算四则混合运算项目

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  9. 现有 Vue.js 项目快速实现多语言切换的一种思路

    Web 项目多语言(i18n,即国际化)是比较常见的需求,常规的做法大概有以下几种: 每种语言单独开发页面,适用于 CMS 之类的网站 多语言文本和页面结构分离,运行时动态替换.适用于单页应用(SPA ...

随机推荐

  1. jQuery与javascript

    jQuery 是一个 JavaScript 库,jQuery 极大地简化了 JavaScript 编程. javaScript(js)和jQuery(jq) 都是找元素.操作元素 Dom操作的区别: ...

  2. Redis之NoSql入门和概述(一)

    1. 为什么用 NoSQL? NoSQL指的是非关系型的数据库,NoSQL也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称.NoSQL用于超大规模数据的存储.这 ...

  3. amazeui 验证按钮扩展

    做一个发送验证码按钮,点击后要60秒之后才能再次点击,利用原有的amazeui样式做的一些扩展,当然主题功能的代码全都是自己写的,也可以脱离amazeUi 自己完成这个功能按钮 代码如下: <! ...

  4. 02_HTML03

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"软件测试"获取视频和教程资料! b站在线视频 HTML ...

  5. Python basestring() 函数

    描述 basestring() 方法是 str 和 unicode 的超类(父类),也是抽象类,每组词 www.cgewang.com 因此不能被调用和实例化,但可以被用来判断一个对象是否为 str ...

  6. PHP define() 函数

    实例 定义一个大小写敏感的常量: <?php define("GREETING","Hello you! How are you today?"); ec ...

  7. Python基础教程 (第2+3 版)打包pdf|内附网盘链接提取码

                <Python基础教程 第3版>包括Python程序设计的方方面面:首先,从Python的安装开始,随后介绍了Python的基础知识和基本概念,包括列表.元组.字符 ...

  8. [USACO09NOV]硬币的游戏 博弈 dp

    LINK : coin game 这道题 超级经典去年这个时候我就看过题目了 但时至今日还不会/cy 觉得在做比赛的题目的时候少写省选的题目 多做水题多做不难也不简单的题目就好了. 由于我是真的不会博 ...

  9. 使用idea 时出现classnotfound

    如果是web项目,而且确定包在.. 不用担心,点开Project structure 在artifacts 选择就好了..双击就可以  包就进lib下了

  10. resultMap的用法以及关联结果集映射

    resultType resultType可以把查询结果封装到pojo类型中,但必须pojo类的属性名和查询到的数据库表的字段名一致. 如果sql查询到的字段与pojo的属性名不一致,则需要使用res ...