WordCount是一個常見的工具,它能統計文本文件的字數、單詞數和行數。在本次項目中,要求寫一個命令行程序,模仿已有的WordCount.exe的功能,並加以擴充,統計出某程序設計語言源文件的字符數、單詞數和行數。在此基礎上,還實現了對某程序設計語言源文件的空行、代碼行和注釋行的統計。
程序處理用戶需求的模式為:
wc.exe [parameter][filename]
各個參數的意義
基本功能列表
wc.exe -c file.c 對字符數的統計
wc.exe -w file.c 對單詞數的統計
wc.exe -l file.c: 對行數的統計
擴展功能
wc.exe -a 對空行、代碼行和注釋行的統計
空行:本行全部是空格或格式控制字符,如果包括代碼,則只有不超過一個可顯示的字符,例如“}”。
代碼行:本行包括多余一個字符的代碼。
注釋行:本行不是代碼行,並且本行包括注釋。
本項目一共分成了四個模塊:分別是字符統計模塊、單詞統計模塊、行數統計模塊和綜合統計模塊,綜合統計模塊包括代碼行、空行和注釋行的統計。設計如下:
void CharCount(); //字符統計函數 void WordCount(); //單詞統計函數 void LineCount(); //行數統計函數 void Muiltiple(); //綜合統計函數,包括代碼行,空行,注釋行
字符統計模塊:
void CharCount() //字符統計函數 { FILE *fp; int c = 0; char ch; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { c ++; ch = fgetc(fp); } printf("char count is :%d.\n",c); fclose(fp); }
本模塊以只讀的方式打開在程序目錄中的file.c文本文件,依次訪問文本文件中的每個字符,統計變量依次加1,直到文本文件結束為止。
單詞統計模塊:
void WordCount() //單詞統計函數 { FILE *fp; int w = 0; char ch; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { if ((ch >= 'a'&&ch <= 'z')||(ch >= 'A'&&ch <='Z')||(ch >= '0'&&ch <= '9')) { while ((ch >= 'a'&&ch <= 'z')||(ch >= 'A'&&ch <= 'Z')||(ch >= '0'&&ch <= '9')||ch == '_') { ch = fgetc(fp); } w ++; ch = fgetc(fp); } else { ch = fgetc(fp); } } printf("word count is :%d.\n",w); fclose(fp); }
本模塊統計的是以字母、數字和下划線組成,且首字母不為下划線的所有單詞。統計過程同字符統計模塊,此處不再贅述。
行數統計模塊:
void LineCount() //行數統計函數 { FILE *fp; int l = 1; char ch; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { if (ch == '\n') { l ++; ch = fgetc(fp); } else { ch = fgetc(fp); } } printf("line count is :%d.\n",l); fclose(fp); }
此模塊行數的初始化為1,依次訪問文本文件中的字符,遇到換行符依次加1,直到文本結束為止。
綜合統計模塊:
void Muiltiple() //綜合統計函數,包括代碼行,空行,注釋行 { FILE *fp; char ch; int c=0,e=0,n=0; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { if (ch == '{'||ch == '}') { e ++; ch = fgetc(fp); } else if (ch == '\n') { ch = fgetc(fp); while(ch == '\n') { e ++; ch = fgetc(fp); } } else if (ch == '/') { ch = fgetc(fp); if (ch == '/') while(ch != '\n') { ch = fgetc(fp); } n ++; ch = fgetc(fp); } else { c ++; while (ch != '{'&&ch != '}'&&ch != '\n'&&ch != '/'&&ch != EOF) { ch = fgetc(fp); } } } printf("code line count is :%d.\n",c); printf("empt line count is :%d.\n",e); printf("note line count is :%d.\n",n); fclose(fp); }
此模塊能夠實現對空行、代碼行和注釋行的統計。依次訪問文本文件中的字符,若該字符為“{”或“}”,則空行變量加1。若該字符為兩個連續的“/”,則注釋行變量加1。否則代碼變量加1。依次循壞,直到文本結束為止。
總模塊的設計:
int main(int argc,char *argv[]) { if ((strcmp(argv[1], "-c") == 0) && (strcmp(argv[2], "file.c") == 0)) { CharCount(); } if ((strcmp(argv[1], "-w") == 0) && (strcmp(argv[2], "file.c") == 0)) { WordCount(); } if ((strcmp(argv[1], "-l") == 0) && (strcmp(argv[2], "file.c") == 0)) { LineCount(); } if ((strcmp(argv[1], "-a") == 0) && (strcmp(argv[2], "file.c") == 0)) { Muiltiple(); } return 0; }
總模塊對命令行參數中字符串數組進行判斷,第一個字符串數組為程序名,若第二個字符串為“-c”、“-w”、“-l”、“-a”,且第三個字符串數組為file.c,則依次調用CharCount、WordCount、LineCount、Muiltiple函數以實現對字符數、單詞數、行數和空行數、代碼行數和注釋行數的統計。
程序運行測試:
需要統計的文本文件:
void main() //main { int x,y,s; scanf("%d%d",&x,&y); s = Add(int x,int y); printf("x + y = %d.",s); } int Add(int x,int y) //Add { return x + y; }
找到程序所在目錄。注:需要統計的文本文件file.c在此目錄中。
字符數的統計測試:
單詞數的統計測試:
行數的統計測試:
對空行數、代碼行數、注釋行數的統計測試:
本次項目任有沒能實現的功能,wc.exe -s遞歸處理目錄下符合條件的文件和wc.exe -x 顯示圖形界面,用戶可以通過界面選取單個文件,程序就會顯示文件的字符數、行數等全部統計信息。對於遞歸處理目錄下符合的文件功能,暫時還沒有能夠很好解決的思想,所以等待下次作業的完善。對於顯示圖形界面的功能,由於還沒有做圖形界面的經歷,再加上本次項目時間有些倉促,也是沒能完美完成。
附上完整代碼:
// WC.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include "string.h" void CharCount(); //字符統計函數 void WordCount(); //單詞統計函數 void LineCount(); //行數統計函數 void Muiltiple(); //綜合統計函數,包括代碼行,空行,注釋行 int main(int argc,char *argv[]) { if ((strcmp(argv[1], "-c") == 0) && (strcmp(argv[2], "file.c") == 0)) { CharCount(); } if ((strcmp(argv[1], "-w") == 0) && (strcmp(argv[2], "file.c") == 0)) WordCount(); } if ((strcmp(argv[1], "-l") == 0) && (strcmp(argv[2], "file.c") == 0)) { LineCount(); } if ((strcmp(argv[1], "-a") == 0) && (strcmp(argv[2], "file.c") == 0)) { Muiltiple(); } return 0; } void CharCount() //字符統計函數 { FILE *fp; int c = 0; char ch; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { c ++; ch = fgetc(fp); } printf("char count is :%d.\n",c); fclose(fp); } void WordCount() //單詞統計函數 { FILE *fp; int w = 0; char ch; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { if ((ch >= 'a'&&ch <= 'z')||(ch >= 'A'&&ch <='Z')||(ch >= '0'&&ch <= '9')) { while ((ch >= 'a'&&ch <= 'z')||(ch >= 'A'&&ch <= 'Z')||(ch >= '0'&&ch <= '9')||ch == '_') { ch = fgetc(fp); } w ++; ch = fgetc(fp); } else { ch = fgetc(fp); } } printf("word count is :%d.\n",w); fclose(fp); } void LineCount() //行數統計函數 { FILE *fp; int l = 1; char ch; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { if (ch == '\n') { l ++; ch = fgetc(fp); } else { ch = fgetc(fp); } } printf("line count is :%d.\n",l); fclose(fp); } void Muiltiple() //綜合統計函數,包括代碼行,空行,注釋行 { FILE *fp; char ch; int c=0,e=0,n=0; if((fp = fopen("file.c","r")) == NULL) { printf("file read failure."); } ch = fgetc(fp); while(ch != EOF) { if (ch == '{'||ch == '}') { e ++; ch = fgetc(fp); } else if (ch == '\n') { ch = fgetc(fp); while(ch == '\n') { e ++; ch = fgetc(fp); } } else if (ch == '/') { ch = fgetc(fp); if (ch == '/') while(ch != '\n') { ch = fgetc(fp); } n ++; ch = fgetc(fp); } else { c ++; while (ch != '{'&&ch != '}'&&ch != '\n'&&ch != '/'&&ch != EOF) { ch = fgetc(fp); } } } printf("code line count is :%d.\n",c); printf("empt line count is :%d.\n",e); printf("note line count is :%d.\n",n); fclose(fp); }