代码改变世界

wc基础功能

2018-09-24 19:21  星河流放  阅读(430)  评论(0编辑  收藏  举报

第一次作业

项目地址

https://gitee.com/xxlznb/WordCount

PSP

WordCount 预估耗时(分钟) 实际耗时
计划 20 30
预估任务需要时间 20 30
开发 380 465
需求分析 20 25
设计文档 10 5
代码规范 10 5
具体设计 40 20
具体编码 240 320
代码复审 40 30
测试 20 60
报告 50 45
测试报告 10 15
计算工作量 10 10
事后总结 30 20
合计 450 540

思路

WordCount的基础功能是

  • 统计字数

    统计字数,只需要将文件中的单词一个个读取出来就行。

  • 统计单词数

    对于一个文本而言,其内容可以抽象为单词+符号,也就是说,计算符号的间隔即可

  • 统计行数

    读取文本中的换行符即可

我的开发平台为Linux,为了符合Linux的基础要求,参考书目为《UNIX环境高级编程(第三版)》

程序实现过程

程序分为两个主要步骤在主函数中我们只需要调用这两个函数

  1. 解析参数

    解析参数,我把参数分为三类,短选项、长选项、文件名,

    • 短参数,以-开始后紧跟一个字符,短参数可以叠加使用,也可以单独使用,例如 -c -l -w
    • 长参数,短参数在使用频繁的时候可能造成输入麻烦,因此,你可以将短参数直接写在一个-后,例如 -c -l -w [file] 可直接简写为-clw [file] 顺序和内容都自由更改
    • 文件名称,文件名称位于参数后,且如果没有参数则会报错,如果一个参数后紧跟多个文件名,则对多个文件执行同等的操作,例如 -clw [file1] [file2] ,但-o参数除外,-o只能指定一个文件

    对于参数解析采取宽容方式 -c -c [file] 重复参数不报错。

    具体做法为构造一个解析链表,将解析结果存入链表中

    同时将执行模式存入其中,为了节约储存空间,将模式直接放入一个int中,之后判断int的位就可以知道它的模式

  2. 统计内容

    统计内容为了方便添加功能,将每个功能单独写一个函数,之后调用函数即可。

代码说明

void putInfo(int x)
{
    if(root==NULL)
    {
        root=(Info*)malloc(sizeof(Info));
        root->mode=x;
        root->path=NULL;
        root->next=NULL;
        tail=root;
    }
    else
    {
        if(tail->path!=NULL)
        {
            tail->next=(Info*)malloc(sizeof(Info));
            tail=tail->next;
            tail->mode=x;
            tail->path=NULL;
            tail->next=NULL;
        }
        else
        {
            tail->mode=(tail->mode|x);
        }
    }
}

void longArg(char* arg)
{
    int length=strlen(arg);
    int i,x=0;
    for(i=1;i<length;i++)
    {
        switch(arg[i])
        {
            case 'c':x=x|c;break;
            case 'w':x=x|w;break;
            case 'l':x=x|l;break;
            default:
            {
                fprintf(stderr,"wc:error:%s of '%s'\n",strerror(EINVAL),arg);
                exit(1);
            }
        }
    }
    putInfo(x);
}
void argParsing(int argc,char* argv[])
{
    char* temp=NULL;
    int i=1;
    while(i<argc)
    {
        if(strcmp(argv[i],"-c")==0)
        {
            putInfo(c);
        }
        else if(strcmp(argv[i],"-w")==0)
        {
            putInfo(w);
        }
        else if(strcmp(argv[i],"-l")==0)
        {
            putInfo(l);
        }
        else if(strcmp(argv[i],"-o")==0)
        {
            if(i<argc-1 && argv[i+1][0]!='-')
            {
                outFilePath=argv[i+1];
                i++;
            }
            else
            {
                fprintf(stderr,"wc:error:'-o' argument no outputfile\n");
                exit(1);
            }
        }
        else if(argv[i][0]=='-')
        {
            if(strlen(argv[i])>2)
            {
                longArg(argv[i]);
            }
            else
            {
                fprintf(stderr,"wc:error:%s of '%s'\n",strerror(EINVAL),argv[i]);
                exit(1);
            }
        }
        else
        {
            if(tail!=NULL)
            {
                if(tail->path!=NULL)
                {
                    putInfo(tail->mode);
                }
                tail->path=argv[i];
            }
            else
            {
                fprintf(stderr,"wc:error:%s of '%s'\n",strerror(EINVAL),argv[i]);
                exit(1);
            }
        }
        i++;
    }
    if(root==NULL||tail->path==NULL)
    {
        fprintf(stderr,"wc:error:no input file\n");
        exit(1);   
    }
    if(outFilePath==NULL)outFilePath="result";
}

这是解析的相关函数,主要就体现一个if else。就考虑到所有的方面就行了,代码有问题的地方在与可复用性不高,而且扩展行差。后期再想办法吧。

测试设计

创建一个test.sh文件,内容如下:

#!/bin/bash
gcc wc.c -o wc -D PRINT -D NOCOUNT
./wc -c -c -l -w file1 
./wc -clw file1 file2
./wc -clw file1 -cl file2
./wc -c
./wc file1
./wc -e file1
./wc -el file1 
./wc -o
./wc -l -o outfile file
./wc -
./wc 

输出内容如下

7,file1
7,file1
7,file2
7,file1
5,file2
wc:error:no input file
wc:error:Invalid argument of 'file1'
wc:error:Invalid argument of '-e'
wc:error:Invalid argument of '-el'
wc:error:'-o' argument no outputfile
1,file
wc:error:Invalid argument of '-'
wc:error:no input file

白盒测试,可能会有没考虑到的地方

参考文献

《UNIX环境高级编程(第三版)》