1. 程式人生 > >WordCount 的實現與測試

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,而且由於自身知識量的不夠在測試或優化時未能盡善盡美,所以我們虛心請教學長還有學霸後最終完成了專案。對專案本身還有一點疑問未能解決,有些演算法也是在網上查詢,不能有效理解,還需要繼續努力。