個人項目作業(wc.exe)
- 2020 年 3 月 15 日
- 筆記
1.GitHub項目地址
https://github.com/QiuBin666/WC
項目介紹:
題目描述
Word Count
1. 實現一個簡單而完整的軟體工具(源程式特徵統計程式)。
2. 進行單元測試、回歸測試、效能測試,在實現上述程式的過程中使用相關的工具。
3. 進行個人軟體過程(PSP)的實踐,逐步記錄自己在每個軟體工程環節花費的時間。
WC 項目要求
wc.exe 是一個常見的工具,它能統計文本文件的字元數、單詞數和行數。這個項目要求寫一個命令行程式,模仿已有wc.exe 的功能,並加以擴充,給出某程式設計語言源文件的字元數、單詞數和行數。
實現一個統計程式,它能正確統計程式文件中的字元數、單詞數、行數,以及還具備其他擴展功能,並能夠快速地處理多個文件。
具體功能要求:
程式處理用戶需求的模式為:
wc.exe [parameter] [file_name]
基本功能列表:
wc.exe -c file.c //返迴文件 file.c 的字元數
wc.exe -w file.c //返迴文件 file.c 的詞的數目
wc.exe -l file.c //返迴文件 file.c 的行數
擴展功能:
-s 遞歸處理目錄下符合條件的文件。
-a 返回更複雜的數據(程式碼行 / 空行 / 注釋行)。
空行:本行全部是空格或格式控制字元,如果包括程式碼,則只有不超過一個可顯示的字元,例如“{”。
程式碼行:本行包括多於一個字元的程式碼。
注釋行:本行不是程式碼行,並且本行包括注釋。一個有趣的例子是有些程式設計師會在單字元後面加註釋:
} //注釋
在這種情況下,這一行屬於注釋行。
[file_name]: 文件或目錄名,可以處理一般通配符。
高級功能:
-x 參數。這個參數單獨使用。如果命令行有這個參數,則程式會顯示圖形介面,用戶可以通過介面選取單個文件,程式就會顯示文件的字元數、行數等全部統計資訊。
需求舉例:
wc.exe -s -a *.c
返回當前目錄及子目錄中所有*.c 文件的程式碼行數、空行數、注釋行數。
2.PSP預計時間
PSP2.1 |
Personal Software Process Stages |
預估耗時(分鐘) |
實際耗時(分鐘) |
Planning |
計劃 |
30 |
|
· Estimate |
· 估計這個任務需要多少時間 |
30 |
|
Development |
開發 |
180 |
|
· Analysis |
· 需求分析 (包括學習新技術) |
200 |
|
· Design Spec |
· 生成設計文檔 |
30 |
|
· Design Review |
· 設計複審 (和同事審核設計文檔) |
0 |
|
· Coding Standard |
· 程式碼規範 (為目前的開發制定合適的規範) |
20 |
|
· Design |
· 具體設計 |
30 |
|
· Coding |
· 具體編碼 |
360 |
|
· Code Review |
· 程式碼複審 |
20 |
|
· Test |
· 測試(自我測試,修改程式碼,提交修改) |
120 |
|
Reporting |
報告 |
120 |
|
· Test Report |
· 測試報告 |
60 |
|
· Size Measurement |
· 計算工作量 |
30 |
|
· Postmortem & Process Improvement Plan |
· 事後總結, 並提出過程改進計劃 |
60 |
|
合計 |
|
1290 |
|
3.解題思路
拿到題目後首先想到的是:要對文件進行讀寫操作,但這是以前的編程經歷中從未涉及到的,所以首先去學習了c語言文件讀寫相關的知識。
學習相關知識後,就到了該如何實現功能的問題了,解決方法是劃分為幾個功能模組,每個模組實現一個功能。
4.設計實現過程
設計字元數統計函數void CharCount():當判定為字元便計數,非字元則不計。
設計單詞數統計函數void WordCount():通過從第一個字母開始讀取連續的字母。
設計行數統計函數 void LineCount():判斷行數可以判斷是否出現‘n’或‘t’來判斷。
設計擴展功能統計函數int Extend():
1、空行計算,如果一行中沒有字元或者最多有一個'{‘或者’}'(可能遇到‘ ’或者‘t’)算為空行。
2、注釋行計算,通過讀取第一個字元為/進入判斷,讀取第二個字元為*或者/實現。
3、程式碼行計算,排除空行和注釋行之外的即為程式碼行。
5.程式碼說明
主函數:
1 int a=0; 2 int b=0; 3 int c=0; 4 int main() { //主函數 5 void CharCount(char filename[]);//字元數統計函數 6 void WordCount(char filename[]);//單詞數統計函數 7 void LineCount(char filename[]);//行數統計函數 8 int Extend(char filename[]);//擴展功能統計函數 9 char input[10], filename[32]; 10 while (1) { 11 //輸入指令 12 printf("wc.exe - c file.c 返迴文件的字元數nwc.exe - w file.c 返迴文件的詞的數目nwc.exe - l file.c 返迴文件的行數nwc.exe - a file.c 返回更複雜的數據(程式碼行 / 空行 / 注釋行)nwc.exe - o file.c 退出n請輸入指令:- "); 13 scanf("%s",&input); 14 15 switch(input[0]){ 16 case 'c': //字元數 17 printf("請輸入文件名:");//輸入文件名 18 scanf("%s", &filename); 19 CharCount(filename); 20 printf("文件的字元數為:%d",a); 21 break; 22 23 case 'w': //詞數 24 printf("請輸入文件名:");//輸入文件名 25 scanf("%s", &filename); 26 WordCount(filename); 27 printf("文件的詞數為:%d", b); 28 break; 29 30 case 'l': //行數 31 printf("請輸入文件名:");//輸入文件名 32 scanf("%s", &filename); 33 LineCount(filename); 34 printf("文件的行數為:%d", c); 35 break; 36 37 case 'a': //返回更複雜的數據(程式碼行 / 空行 / 注釋行)。 38 printf("請輸入文件名:");//輸入文件名 39 scanf("%s", &filename); 40 Extend(filename); 41 break; 42 43 case 'o': //退出 44 return 0; 45 46 default: 47 printf("你輸入的指令有誤!請重新輸入"); 48 break; 49 } 50 51 } 52 system("pause"); 53 return 0; 54 }
各子模組功能函數:
計算字元數:
1 void CharCount(char filename[]){//字元數統計函數 2 FILE *fp=NULL; 3 fp=fopen(filename,"r"); 4 if(fp==NULL){ 5 printf("尋找文件失敗n"); 6 exit(-1); 7 } 8 char ch; 9 ch = fgetc(fp); 10 while(ch!=EOF){ 11 if (ch != ' '&&ch != 'n'&&ch != 't'&&ch != ','&&ch != '.'&&ch != '!'&&ch != ';'&&ch != '='); 12 a++; 13 ch = fgetc(fp); 14 } 15 a--; 16 fclose(fp); 17 }
計算詞數:
1 void WordCount(char filename[]){//單詞數統計函數 2 FILE *fp = NULL; 3 fp=fopen(filename,"r"); 4 if(fp==NULL){ 5 printf("尋找文件失敗n"); 6 exit(-1); 7 } 8 char fchar = 0; 9 fchar = fgetc(fp); 10 while (fchar != EOF) 11 { 12 if ((fchar >= 'a' && fchar <= 'z') || (fchar >= 'A' && fchar <= 'Z') )//遇到字母 13 { 14 while ((fchar >= 'a' && fchar <= 'z') || (fchar >= 'A' && fchar <= 'Z')) 15 fchar = fgetc(fp); 16 b++; 17 fchar = fgetc(fp); 18 } 19 else { 20 fchar = fgetc(fp); 21 } 22 } 23 fclose(fp); 24 25 }
計算行數:
1 void LineCount(char filename[]){//行數統計函數 2 FILE *fp = NULL; 3 fp=fopen(filename,"r"); 4 if(fp==NULL){ 5 printf("尋找文件失敗n"); 6 exit(-1); 7 } 8 char ch; 9 ch = fgetc(fp); 10 while (ch != EOF) 11 { 12 if (ch == 'n' || ch == 't') 13 c++; 14 ch = fgetc(fp); 15 } 16 fclose(fp); 17 }
擴展功能函數:
1 int Extend(char filename[]) { //擴展功能 2 FILE *fp = NULL; 3 fp = fopen(filename, "r"); 4 if (fp == NULL) { 5 printf("尋找文件失敗n"); 6 exit(-1); 7 } 8 9 char fchar = 0; 10 int emptyline = 0, code = 0, note = 0; 11 int l = 0, n = 0, c = 0;//l為空行類型,0是無字元空行,1是1字元空行;n為注釋類型,0為非注釋行,1為單注釋行,2為多注釋行,c為程式碼類型 12 13 while (fchar != EOF) { 14 fchar = fgetc(fp); 15 if (l == 0 || l == 1) {//如果開始是空格或製表,開始判斷是不是空行或者注釋行或者程式碼行 16 if (fchar == 'n') {//回車之前沒有字元,空行;1字元進入後也是沒有其他字元 17 emptyline++; 18 l = 0; 19 continue; 20 } 21 else if (fchar == '/') {//注釋判斷 22 fchar = fgetc(fp); 23 if (fchar == '/') {//單行注釋 24 n = 1; 25 while (fchar != EOF && fchar != 'n') { 26 fchar = fgetc(fp); 27 } 28 n = 0; 29 note++; 30 continue; 31 } 32 else if (fchar == '*') {//多行注釋 33 n = 2; 34 continue; 35 } 36 } 37 else if( fchar == '}' && l == 0){ 38 l = 1; //一字元空行 39 continue; 40 } 41 else if(fchar == ' ' || fchar == 't'){ 42 continue; 43 } 44 else { 45 c = 1; 46 } 47 } 48 if (c == 1) {//程式碼行 49 while (fchar != EOF && fchar != 'n') { 50 fchar = fgetc(fp); 51 } 52 l = 0;//狀態變回空行 53 code++; 54 continue; 55 } 56 if (n == 2) {//多行注釋 57 while (fchar != EOF && fchar != '*') { 58 while (fchar != EOF && fchar != 'n') { 59 fchar = fgetc(fp); 60 } 61 note++; 62 fchar = fgetc(fp); 63 } 64 fchar = fgetc(fp); 65 if (fchar == '/') {//多行結束 66 n = 0; 67 } 68 continue; 69 } 70 } 71 printf("n共有空行數: %d n程式碼行數: %d n注釋行數: %dn", emptyline, code, note); 72 fclose(fp); 73 }
6.測試運行
基本功能測試用例
測試-c功能:
測試-w功能:
測試-l功能:
擴展功能測試用例
測試-a功能:
7.實際花費的時間
PSP2.1 |
Personal Software Process Stages |
預估耗時(分鐘) |
實際耗時(分鐘) |
Planning |
計劃 |
30 |
35 |
· Estimate |
· 估計這個任務需要多少時間 |
30 |
20 |
Development |
開發 |
180 |
240 |
· Analysis |
· 需求分析 (包括學習新技術) |
200 |
180 |
· Design Spec |
· 生成設計文檔 |
30 |
20 |
· Design Review |
· 設計複審 (和同事審核設計文檔) |
0 |
0 |
· Coding Standard |
· 程式碼規範 (為目前的開發制定合適的規範) |
20 |
10 |
· Design |
· 具體設計 |
30 |
60 |
· Coding |
· 具體編碼 |
360 |
540 |
· Code Review |
· 程式碼複審 |
20 |
60 |
· Test |
· 測試(自我測試,修改程式碼,提交修改) |
120 |
180 |
Reporting |
報告 |
120 |
100 |
· Test Report |
· 測試報告 |
60 |
30 |
· Size Measurement |
· 計算工作量 |
30 |
20 |
· Postmortem & Process Improvement Plan |
· 事後總結, 並提出過程改進計劃 |
60 |
40 |
合計 |
|
1290 |
1535 |
8.項目小結
收穫:作為第一次項目經歷,對軟體工程的設計流程有了新的認識,一個項目的實現,重要的往往不是程式碼的品質,而是一個好的框架和一個良好的開發習慣,在這次開發過程中深刻的認識到這兩點的重要性。
不足:基礎知識的不足,導致前期準備時間過長。解決問題能力不足,導致編碼所需時間長、錯誤多,部分功能完全沒能力實現,需多學、多練。開發經驗少,整個開發過程並不流暢。