第二周作业 WordCount

1. github 地址: 

  https://github.com/XueRui97/WCProject

2. PSP表格:

PSP2.1PSP阶段预估耗时(分钟)实际耗时(分钟)
· Planning · 计划 60 50
· Estimate · 估计这个任务需要多少时间 40 30
· Development · 开发 400 450
· Analysis · 需求分析 (包括学习新技术) 60 40
· Design Spec · 生成设计文档 40 30
· Design Review · 设计复审 (和同事审核设计文档) 30 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 20
· Design · 具体设计 60 130
· Coding · 具体编码 400 550
· Code Review · 代码复审 200 350
· Test · 测试(自我测试,修改代码,提交修改 120 180
· Reporting · 报告 100 120
· Test Report · 测试报告 180 200
· Size Measurement · 计算工作量 40 30
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 50
  · 合计 1820 2260

3. 解题思路:

  • 首先看到题目要求的用命令行参数的形式输入,就是需要用到main函数的argv参数。然后就想到,要相对不同的输入采取不同的模式,首先需要对输入的参数识别。这时,我便想有没有能够解析命令行参数的函数。然后便找到了getopt()这个函数,能够方别地解析命令行参数。
  • 解决了解析参数问题后,还有就是读取输入文件的内容,以及保存处理结果需要用到写入文件。
  • 然后重点就在于中间的处理过程,查行数,单词数,和字符数倒是比较简单。难点在于如何辨别代码行,空行以及注释行。而且这一点由于需求不太明确,所以需要花费很长时间。

4. 程序实现:

  我是采用C语言实现的,采用面向过程编程的方式。把从头到尾的过程分成几部分,然后编写对应的函数。首先是解析命令行参数的函数,由这个函数可以获得输入的模式,以及输入输出的文件名。然后是查行数,单词数,和字符数。这三个功能相对来说比较简单,只需一次读取文件就能够完成这三个功能,所以便放在一个函数里。然后是处理代码行,空行,注释行,这三个较为麻烦,但是中间处理的过程比较类似,所以也放在一个函数里。最后保存结果也需要用一个函数来实现。实现递归处理文件也需要一个函数处理。

5. 代码说明:

  解析命令行参数:

while((opt=getopt(argc,argv,"a:s:l:w:c:o:")) != -1)
    {
        switch(opt)
        {
            case 'a':    //返回更复杂的数据(代码行 / 空行 / 注释行)
                a = 1;
                strcpy(inputFileName,optarg);
                break;
            case 's':    //递归处理目录下符合条件的文件
                l = w = c = 1;
                strcpy(inputFileName,optarg);
                break;
            case 'l':    //行数
                l = 1;
                strcpy(inputFileName,optarg);
                break;  
            case 'w':    //单词数
                w = 1;
                strcpy(inputFileName,optarg); 
                break;  
            case 'c':    //字符数
                c = 1;
                strcpy(inputFileName,optarg);
                break;
            case 'o':    //输出文件
                o = 1;
                strcpy(outputFileName,optarg);  
        }
    }

  统计单词,行,字符数:

int countFile(char *filename){
    FILE *fp;  // 指向文件的指针
    char buffer[1003];  //缓冲区,存储读取到的每行的内容
    int bufferLen;  // 缓冲区中实际存储的内容的长度
    int i;  // 当前读到缓冲区的第i个字符
    char c;  // 读取到的字符
    int isLastBlank = 0;  // 上个字符是否是空格
    int charNum = 0;  // 当前行的字符数
    int wordNum = 0; // 当前行的单词数
    if( (fp=fopen(filename, "rb")) == NULL ){
        perror(filename);
        return -1;
    }
    //printf("line   words  chars\n");
    // 每次读取一行数据,保存到buffer,每行最多只能有1000个字符
    while(fgets(buffer, 1003, fp) != NULL){
        bufferLen = strlen(buffer);
        // 遍历缓冲区的内容
        for(i=0; i<bufferLen; i++){
            c = buffer[i];
            if( c==' ' || c=='\t'){  // 遇到空格
                !isLastBlank && wordNum++;  // 如果上个字符不是空格,那么单词数加1
                isLastBlank = 1;
            }else if(c!='\n'&&c!='\r'){  // 忽略换行符
                charNum++;  // 如果既不是换行符也不是空格,字符数加1
                isLastBlank = 0;
            }
        }
        !isLastBlank && wordNum++;  // 如果最后一个字符不是空格,那么单词数加1
        isLastBlank = 1;  // 每次换行重置为1
        // 一行结束,计算总字符数、总单词数、总行数
        lineCnt++;  // 总行数
        charCnt += charNum;  // 总字符数
        wordCnt += wordNum;  // 总单词数
        // 置零,重新统计下一行
        charNum = 0;
        wordNum = 0;
    }
    fclose(fp);
    return 1;
}

  递归处理输入文件:

  辨别代码行,空行,注释行:

  保存文件:

int writeOutput(char *outFile, char *inFile)
{
    FILE *fpWrite = fopen(outFile,"w");
    if (fpWrite == NULL)
        return -1;
    fprintf(fpWrite, "%s,", inFile);
    if (l)
    {
        fprintf(fpWrite, "行数: %d,", lineCnt);
    }
    if (w)
    {
        fprintf(fpWrite, "单词数: %d,", wordCnt);
    }
    if (c)
    {
        fprintf(fpWrite, "字符数: %d\n\n", charCnt);
    }
    fclose(fpWrite);
}

 

6. 测试设计过程:

  测试方法:白盒测试

  WordCount只有一个模式(即-c -w -l -o)时,运行路径如下图:

 

  

  设计测试用例思路:设计出的测试用例需要能覆盖程序的所有功能,即把每一条路径都走一遍。同时,还要测试在输入参数不正确的情况下,程序会如何运行。总之,就是把程序的所有的可能的情况都运行一遍。

  测试重点:重点在于对参数的判断以及执行相应的分支,以及错误情况下的运行。

  10个测试用例分别为:

  1. wc.exe -l test.txt  2. wc.exe -w test.txt  3. wc.exe -c test.txt  4. wc.exe -l  5. wc.exe -l test.txt -o output.txt  6. wc.exe -w test.txt -o output.txt  

  7. wc.exe -c example.txt -o output.txt  8. wc.exe -o output.txt  9. wc.exe -w -c test.txt  10. wc.exe -c -l -w test.txt -o output.txt 

  其中 1,2,3,5,6,9,10都为正常输入,能够正常输出结果,没有-o的默认保存到result.txt,有-o的保存到-o后面的文件。

  4,7,8为3种错误的输入,4没有输入文件,运行后会出现错误提示提示,输入错误,没有输入文件。

  7的输入文件example.txt不存在当前目录下,即输入文件不存在,此时会出现错误提示,没有找到输入文件。

  8的输入没有输入文件,但有输出文件,此时会提示,输入错误,没有输入模式。

  总结:正确输入都能够输出正确的结果,错误的输入能输出对应的错误提示。

7. 参考资料链接:

  [1]http://www.cnblogs.com/runnyu/p/4943704.html

  [2]http://www.cnblogs.com/Ming8006/p/5798186.html

  [3]http://blog.csdn.net/y1196645376/article/details/53365909

  

 

posted @ 2018-03-20 22:54  yeeeti  阅读(231)  评论(2编辑  收藏  举报