WordCount 的实现与测试

一、开头

(1)合作者:201631062627,201631062427

(2)代码地址:https://gitee.com/catchcatcat/WordCount.git

二、正文

(1)基本功能

                统计file.c的字符数(实现)

int CharacterCount(char *Character) {    //字符个数的计算 
    
    FILE *file = fopen(Character, "r");
    assert(file != NULL);    //容错处理 

    char character;
    int count = 0;

    while ((character = fgetc(file)) != EOF)     //读取字符直到结束 
            count+= ((character != ' ') && (character != '\n') && (character != '\t'));    //判断输入是否是字符并合法    

    fclose(file);

    return count;
}

 

                统计file.c的单词数(实现)

int WordCount(char *Character) {    //单词个数的计算 

    FILE *file = fopen(Character, "r");
    assert(file != NULL);

    char word;
    int isword = 0;    //用于记录字符是否处于单词中
    int count = 0;

    while ((word = fgetc(file)) != EOF) {
        if ((word >= 'a' && word <= 'z') || (word >= 'A' && word <= 'Z')) {    //判断输入是否是字母并合法            
            count += (isword == 0);
            isword = 1;    //记录单词状态
        }
        else 
            isword = 0;    //记录不处于单词状态
    }
    fclose(file);

    return count;
}

 

                统计file.c的行数(实现)

void AllDetail(char *Character) {    //显示空行, 代码行,注释行
    
    FILE *file = fopen(Character, "r");
    assert(file != NULL);

    char *s = (char*)malloc(200 * sizeof(char));//申请内存空间
    int i;    
    int is_codeline = 0;    //状态记录变量
    int is_annoline = 0;    
    int AnnoLock = 0;
    int AnnoFileLock = 0;
    
    int codecount = 0;
    int annocount = 0;
    int blankcount = 0;
    
    while (fgets(s, 200, file) != NULL) {    //逐次取文件中的行
        for (i = 0; *(s+i) != '\0'; i++) {
            
            if ( ( ( *(s+i) >= 'a' && *(s+i) <= 'z') || ( *(s+i) >= 'A' && *(s+i) <= 'Z') ) && AnnoFileLock == 0) {//判断是否是代码行
                codecount += (is_codeline == 0 && AnnoLock == 0);    //进入代码行的时候代码行加一                    
                is_codeline = 1;
            }

            if ( *(s+i) == '/' && *(s+i+1) == '/' && is_codeline == 0 && AnnoFileLock == 0){    //判断是否为注释行
                    annocount++;
                    AnnoLock = 1;
            }

            if (*(s + i) == '/' && *(s + i + 1) == '*'){    //判断文档注释开始
                AnnoFileLock = 1;
                annocount -= is_codeline;    //注释在代码后不算注释行,减一
            }

            if (*(s + i) == '*' && *(s + i + 1) == '/') {    //判断文档注释结束
                AnnoFileLock = 0;
                annocount += (*(s + i + 2) == '\n');    //注释后换行情况
            }
        }        
        annocount += AnnoFileLock;    //注释行结束时算作注释行加一

        blankcount++;    //每一行结束计数加一,并清空状态
        is_codeline = 0;
        is_annoline = 0;
        AnnoLock = 0;
    }
    free(s);
    fclose(file);

    blankcount = blankcount - codecount - annocount;    
    printf("codeline:%d, annoline:%d, blankline:%d\n", codecount, annocount, blankcount);
}

int LineCount(char *Character) {    //行数的计算 

    FILE *file = fopen(Character, "r");
    assert(file != NULL);

    char *s = (char*)malloc(200 * sizeof(char));
    int count = 0;
    
    for (; fgets(s, 200, file) != NULL; count++);    //逐次读行

    free(s);
    fclose(file);

    return count;
}

 

        拓展功能

               递归处理目录下符合类型的文件(实现)

void Scan(char *Character, char Test1) {
    char *FileName = NULL;
    char *FileType = NULL;
    char Temp[30];    
    long Head;
    struct _finddata_t FileData;
    int i = 0;

    FileName = Character;
    while (*(Character + i) != '\0') {    //找出文件名和文件类型的位置
        if (*(Character + i) == '\\')
            FileName = Character + i + 1;
        if (*(Character + i) == '.')
            FileType = Character + i + 1;
        i++;
    }
    
    strcpy(Temp, FileType);//调整字符串状态
    *FileType = '*';
    *(FileType + 1) = '\0';
    
    Head = _findfirst(Character, &FileData);
    
    strcpy(FileType, Temp);//恢复字符串状态

    do {
        if ( !strcmp(FileData.name, "..") || !strcmp(FileData.name, "."))    //删除前驱文件路径
            continue;
        
        if (_A_SUBDIR == FileData.attrib)    //如果是文件夹
        {    
            strcpy(Temp, FileName);    //调整字符串状态 
            for (i = 0; *(FileData.name + i) != '\0'; i++) {
                *(FileName + i) = *(FileData.name + i);
            }
            *(FileName + i) = '\\';
            *(FileName + i + 1) = '\0';
            strcat(Character, Temp);

            Scan(Character, Test1);

            strcpy(FileName, Temp);    //恢复字符串状态            
        }
        else//如果是文件的话 
        {    
            for (i = 0; *(FileData.name + i) != '.'; i++);
            if (!strcmp(FileData.name + i + 1, FileType)) {    //如果是指定的类型文件
                
                strcpy(Temp, FileName);
                strcpy(FileName, FileData.name); //调整字符串状态 
                
                printf("%s:  ", FileData.name);
                Start(Test1, NULL, Character);    //将地址及功能传递到启动函数
                printf("\n");

                strcpy(FileName, Temp);//恢复字符串
            }
        }
    } while (_findnext(Head, &FileData) == 0);

    _findclose(Head);    
}

 

               显示代码行、空行、和注释行的行数(实现)附在行数统计

  (2)代码互审情况

大部分的代码都没有问题,在主函数传递和计算单词量时出现了一些函数传递不一致和变量问题,已修改

int WordCount(char *Character) {    //单词个数的计算 

    FILE *file = fopen(Character, "r");
    assert(file != NULL);

    char word;
    int isword = 0;    //用于记录字符是否处于单词中
    int count = 0;

    while ((word = fgetc(file)) != EOF) {
        if ((word >= 'a' && word <= 'z') || (word >= 'A' && word <= 'Z')) {    //判断输入是否是字母并合法            
            count += (isword == 0);
            isword = 1;    //记录单词状态
        }
        else 
            isword = 0;    //记录不处于单词状态
    }
    fclose(file);

    return count;
}
int main(int argc, char *argv[]) {
    
    char Character[99] = "*.c";    //给定的默认参数
    char Test1 = 's';
    char Test2 = 'c';

    if (argv[1]) {    //有输入参数则以输入为准
        Test1 = *(argv[1] + 1);
        if (Test1 == 's') {
            Test2 = *(argv[2] + 1);
            strcpy(Character, argv[3]);
        }
        else
            strcpy(Character, argv[2]);
    }

    Start(Test1, Test2, Character);    //调用启动函数

    printf("\n请输入任意字符以继续...");
    getchar();

    return 0;
}

 

(3)静态代码检查情况

我将C++代码放在如图所示的文件夹中欧冠,但是运用CPPCHECK试着去做,测试结果显示了基础信息和未发现错误

 

 

(4)单元测试情况

测试行数

 

测试单词数

 

测试字符数

 

 

(5)性能测试和优化

性能测试选择.JProfiler

性能测试有些难以使用,并且有许多地方不懂,询问同学和学长都很少有涉及到的,所以暂时放下了这个点

三、实验总结

这次项目的合作对于我们来说是比较困难的。因为之前的代码量比较少,所以很多功能在实现和合并时出现很多BUG,而且由于自身知识量的不够在测试或优化时未能尽善尽美,所以我们虚心请教学长还有学霸后最终完成了项目。对项目本身还有一点疑问未能解决,有些算法也是在网上查询,不能有效理解,还需要继续努力。

 

posted on 2018-10-21 19:44  是有一只猫出没  阅读(209)  评论(0)    收藏  举报