当前位置: 首页 > news >正文

WordCount

写在最前:

参考17079张武科同学的代码,故博文中形如详细代码设计等部分引用了张武科的博文,具体引用部分不详细标出,其他部分仍为本人原创

github地址

https://github.com/mrlandiao/wc

PSP表格

PSP2.1

PSP阶段

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

25

45

· Estimate

· 估计这个任务需要多少时间

25

35

Development

开发

700

1000

· Analysis

· 需求分析 (包括学习新技术)

150

200

· Design Spec

· 生成设计文档

10

20

· Design Review

· 设计复审 (和同事审核设计文档)

30

35

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

10

20

· Design

· 具体设计

60

70

· Coding

· 具体编码

600

700

· Code Review

· 代码复审

100

150

· Test

· 测试(自我测试,修改代码,提交修改)

200

200

Reporting

报告

80

100

· Test Report

· 测试报告

30

40

· Size Measurement

· 计算工作量

10

20

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

15

25

 

合计

2045

2660

解题思路

参考上学期编写的词法分析和语法分析程序的基本功能,对其进行修改,得到main函数。利用控制台执行exe文件,通过传参的不同来实现所要求的功能

程序设计实现过程

本项目采用C语言实现,除main函数外,还有多个自定义函数,其中两个最主要的函数为count()和none(),count()用来统计单词数、行数、注释行数,none()用来统计空行数。

main()函数根据传入的形参的不同,完成不同的输出。其余自定义行数比较简单,下面代码说明中会以isNewline()函数为例进行解释。

代码说明

count()函数用以统计单词数、行数、注释行数,函数中有单词判断,没检测出一个单词word_num+1;每遇到一个'\n',line_num+1;没有到注释行,note_num+1,如果是/*note*/注释,在主是内部没出现一次‘\n’,note_num+1。

复制代码
int count()//统计单词数、行数、注释行数
{
    get();
    clearToken();
    while (isSpace(ch) || isNewline(ch) || isTab(ch) || isComma(ch))
    {
        if (isNewline(ch)) line_num++;
        get();
    }
    if (isStar(ch))
    {
        catToken(ch);
    }
    else if (isDivi(ch))
    {
        catToken(ch);
        get();
        if (isStar(ch))
        {
            note_num++;
            catToken(ch);
            do
            {
                do
                {
                    get();
                    if (isNewline(ch))
                    {
                        note_num++;
                        line_num++;
                    }

                } while (!isStar(ch));
                do
                {
                    get();
                    if (isNewline(ch))
                    {
                        note_num++;
                        line_num++;
                    }
                    if (isDivi(ch))
                    {
                        catToken(ch);
                        return 0;
                    }
                } while (isStar(ch));
            } while (!isStar(ch));
        }
        if (isDivi(ch))
        {
            catToken(ch);
            do
            {
                get();
            } while (!isNewline(ch));
            note_num++;
        }
        if (isNewline(ch))
            line_num++;
    }
    else if (isEnd(ch))
        return 0;
    else
    {
        while (!(isSpace(ch) || isNewline(ch) || isTab(ch) || isComma(ch) || isDivi(ch)))
        {
            catToken(ch);
            get();
        }
        retract();
        if(strcmp(stopWord, "") == 0 || strcmp(token,stopWord)!=0)
           word_num++;
    }
    return 0;
}
复制代码

以isNewline()为例,解释简单自定义函数:

复制代码
bool isNewline(char a)
{
    if (a == '\n')
        return true;
    return false;
}
复制代码

none()函数,根据两个‘\n’中是否小于或等于一个字符来判断是否为空行,满足条件则none_num+1:

复制代码
void none()//统计空行数
{
    int i,j = 0;
    for (i = 0;; i++)
    {
        if (art[i] == EOF)
            break;
        if (art[i] != '\n'&& art[i] != '\t'&& art[i] != ' ')
        {
            j++;
        }
        if (art[i] == '\n')
        {
            if (j <= 1)
                none_num++;
            j = 0;
        }
    }
}
复制代码

main()函数,由于功能是逐步添加的,加上自己的代码习惯有待提高,导致main()函数被修改的过于冗杂。重要思想:利用数组flag[7],每一个元素对应一个功能(包括字符数、单词数输出等),为1时表示对应功能执行,反之不执行。

复制代码
int main(char argc, char* argv[])
{

    if (argc<3)
        printf("请在控制台输入正确命令!\n");
    else
    {
        if (strcmp(argv[0], "wc.exe") != 0)
            printf("可执行文件名输入错误!\n");
        else
        {
            for (int i = 1; i<argc; i++)
            {
                if (strcmp(argv[i], "-c") == 0)
                {
                    flag[0] = 1;
                }
                else if (strcmp(argv[i], "-w") == 0)
                {
                    flag[1] = 1;
                }
                else if (strcmp(argv[i], "-l") == 0)
                {
                    flag[2] = 1;
                }
                else if (strcmp(argv[i], "-o") == 0)
                {
                    flag[3] = 1;
                }
                else if (strcmp(argv[i], "-s") == 0)
                {
                    flag[4] = 1;
                }
                else if (strcmp(argv[i], "-a") == 0)
                {
                    flag[5] = 1;
                }
                else if (strcmp(argv[i], "-e") == 0)
                {
                    flag[6] = 1;
                }
            }
        }
    }

    if (flag[4] == 1)
    {
        _finddata_t sFind;
        long lResult = 0;
        lResult = _findfirst("*.c", &sFind);
        if (lResult == -1) {
            printf("没有找到文件。");
            return 0;
        }

        int i=0,len;
        do {
            len = strlen(sFind.name);
            strcpy_s(filesName[i], len + 1, sFind.name);//将所有读到的保存到filesname
            file_num++;
            i++;
        } while (_findnext(lResult, &sFind) != -1);
    
        for (int j = 0; j < file_num; j++)
        {
            fopen_s(&fp, filesName[j], "r");
            if (fp == NULL)
                printf("error!\n");
            int i = 0;
            do//获取文件内容
            {
                ch = fgetc(fp);
                art[i++] = ch;
            } while (ch != EOF);
            fclose(fp);
            char_num = i;

            if (flag[6] == 1)//获取停用词
            {
                fopen_s(&fp, "stopList.txt", "a");
                fgets(stopWord, 20, fp);
                fclose(fp);
            }
            do//核心统计
            {
                count();
            } while (!isEnd(ch));
            none();
    
            if (flag[0] == 1)
                printf("%s,字符数: %d \n", filesName[j], char_num);
            if (flag[1] == 1)
                printf("%s,单词数: %d \n", filesName[j], word_num);
            if (flag[2] == 1)
                printf("%s,总行数: %d \n", filesName[j], line_num);
            if (flag[3] == 1)
            {
                fopen_s(&fp, argv[argc - 1], "a");
                if (flag[0] == 1)
                    fprintf(fp, "%s,字符数: %d \n", filesName[j], char_num);
                if (flag[1] == 1)
                    fprintf(fp,"%s,单词数: %d \n", filesName[j], word_num);
                if (flag[2] == 1)
                    fprintf(fp,"%s,总行数: %d \n", filesName[j], line_num);
                if (flag[5] == 1)
                    fprintf(fp, "%s,代码行/空行/注释行: %d/%d/%d \n", filesName[j], line_num - note_num - none_num, none_num, note_num);
                fclose(fp);
            }
            if (flag[5] == 1)
                printf("%s,代码行/空行/注释行: %d/%d/%d \n", filesName[j], line_num - note_num - none_num, none_num, note_num);
            strcpy_s(stopWord,1,"");
            for (int i = 0; i < 1000; i++)
                art[i] = '\0';
            sta = art;
            char_num = 0;
            word_num = 0;
            line_num = 0;
            note_num = 0;
            none_num = 0;
        }
    }

    else
    {
        fopen_s(&fp, "file.c", "r");
        if (fp == NULL)
            printf("error!\n");
        int i = 0;
        do
        {
            ch = fgetc(fp);
            art[i++] = ch;
        } while (ch != EOF);
        fclose(fp);
        char_num = i;

        if (flag[6] == 1)
        {
            fopen_s(&fp, "stopList.txt", "r");
            fgets(stopWord, 20, fp);
            fclose(fp);
        }
        do
        {
            count();
        } while (!isEnd(ch));
        none();

        if (flag[0] == 1)
            printf("file.c,字符数: %d \n", char_num);
        if (flag[1] == 1)
            printf("file.c,单词数: %d \n", word_num);
        if (flag[2] == 1)
            printf("file.c,总行数: %d \n", line_num);
        if (flag[3] == 1)
        {
            fopen_s(&fp, argv[argc - 1], "w");
            if (flag[0] == 1)
                fprintf(fp, "file.c,字符数: %d \n", char_num);
            if (flag[1] == 1)
                fprintf(fp, "file.c,单词数: %d \n", word_num);
            if (flag[2] == 1)
                fprintf(fp, "file.c,总行数: %d \n", line_num);
            if (flag[5] == 1)
                fprintf(fp, "file.c,代码行/空行/注释行: %d/%d/%d \n", line_num - note_num - none_num, none_num, note_num);
            fclose(fp);
        }
        if (flag[5] == 1)
            printf("file.c,代码行/空行/注释行: %d/%d/%d \n", line_num - note_num - none_num, none_num, note_num);
    }
    printf("\n");
    system("pause");
    return 0;
}
复制代码

测试设计过程

利用“wc.bat”脚本程序,批量处理,测试用例如下:

测试结果为

测试数据集是我自己随意输入的,详情参见同目录下file.c文件,测试输出结果我已经检查,确认无误。需要说明的是其中仅包含 “ { ” 的行算作空行,不算作代码行。

 另外,当“-s”和“-o”命令同时输入时,写入文件之前不会清空文件;仅包含“-o”命令而不包含“-s”命令时,写入文件之前会清空文件。

参考文献

1.https://www.cnblogs.com/saolv/p/7793379.html

2.https://www.cnblogs.com/chengxs/p/5309215.html

3.https://www.cnblogs.com/MrZhang145689/p/8613206.html

 

转载于:https://www.cnblogs.com/mrlandiao/p/8626654.html

相关文章:

  • 外卖也智能!美团骑手智能助手的技术与实践
  • 【协议转换和消息路由】camel-spring-boot-starter 实践
  • 坑货!阿里奇门中心
  • [ssh]如何设计ARM板上多用户key登录系统
  • 71. Simplify Path
  • numpy 数组运算
  • Java 选择排序selection sort
  • 磁盘管理
  • 利用SCVMM 2012 R2来管理Azure虚拟机
  • AlphaGo告诉我们人工智能成功的五大秘诀,AI下一个风口在哪里?
  • 互联网面临新挑战,区块链经济将兴起
  • 2016年全球IDC市场规模达到451.9亿美元,增速达17.5%
  • YII2中查询生成器Query()的使用
  • notepad++(NPP) 任意多光标编辑,超越列块模式
  • JAVA jdk安装教程及环境变量配置
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • rc-form之最单纯情况
  • React的组件模式
  • Selenium实战教程系列(二)---元素定位
  • SpringBoot几种定时任务的实现方式
  • TypeScript迭代器
  • WePY 在小程序性能调优上做出的探究
  • 一道面试题引发的“血案”
  • 因为阿里,他们成了“杭漂”
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • ​io --- 处理流的核心工具​
  • ###项目技术发展史
  • #pragma pack(1)
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (论文阅读40-45)图像描述1
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (三)终结任务
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .Net 6.0 处理跨域的方式
  • .NET Core WebAPI中封装Swagger配置
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • /etc/sudoer文件配置简析
  • ??在JSP中,java和JavaScript如何交互?
  • [2016.7.Test1] T1 三进制异或
  • [AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [CakePHP] 在Controller中使用Helper
  • [C语言]——内存函数
  • [Electron] 将应用打包成供Ubuntu、Debian平台下安装的deb包
  • [IE编程] 如何在IE8 下调试BHO控件/工具栏(调试Tab进程)
  • [LeetCode] Longest Common Prefix 字符串公有前序
  • [LeetCode] NO. 169 Majority Element
  • [LeetCode]-Pascal's Triangle III 杨辉三角问题
  • [moka同学笔记]yii表单dropdownlist样式
  • [na]wac无线控制器集中转发部署的几种情况