第二周个人作业:WordCount

github地址

https://github.com/lzwk/WordCount

PSP表格

PSP2.1

PSP阶段

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

20

40

· Estimate

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

20

30

Development

开发

600

900

· Analysis

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

100

150

· Design Spec

· 生成设计文档

20

30

· Design Review

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

60

70

· Coding Standard

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

10

20

· Design

· 具体设计

50

55

· Coding

· 具体编码

500

600

· Code Review

· 代码复审

150

200

· Test

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

200

200

Reporting

报告

100

120

· Test Report

· 测试报告

40

50

· Size Measurement

· 计算工作量

20

30

· Postmortem & Process Improvement Plan

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

20

30

 

合计

1910

2525

解题思路

利用控制台执行exe文件,同时传入main()函数的形参,根据传入的形参的不同执行相应的功能,如:字符数、单词数、行数等,不同的输入搭配可以实现不同的高级功能。

程序设计实现过程

本项目采用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”脚本程序,批量处理,测试用例如下:

 

测试结果如下:

 

测试用例中,利用“-o”功能将输出写入文件,其中与“-s”功能同时实现时,写入文件是不会首先清空文件;不与“-s”功能同时实现时,写入文件时会首先清空文件。

可编辑wc.bat来改变测试输入。

参考文献

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

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

 

posted @ 2018-03-20 22:21  非无不可  阅读(205)  评论(2编辑  收藏  举报