WC.exe-軟工作業(一)
阿新 • • 發佈:2018-12-09
專案要求
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 檔案的程式碼行數、空行數、註釋行數。
遇到的困難及解決方法
1.困難描述
- 原本自己是對前端和設計比較感興趣,也在學相關方面的知識,對JavaScript相對比較熟悉,所以一開始產生了用JavaScript來完成這個任務的想法。所以就開始查閱資料,用Node.js+Commander.js 開發命令列程式。但是在真正看需求的時候,發現JavaScript是指令碼語言,對於實現具體的功能還是比較麻煩的。
- 後來換成了自己在大一學過的C語言,由於很久沒有接觸過面向過程語言,很多東西都忘得差不多了。
2. 做過哪些嘗試
用谷歌引擎查閱相關的資料,檢視一些別人分享的部落格。
3.是否解決
解決了,最後確定用C語言,再一步步查閱資料,慢慢debug,做出了基本功能和拓展功能。
4.有何收穫
第一次一個人從頭開始做出一個小型程式,也是第一次用C語言做命令列程式,以前不太喜歡C語言,感覺面向過程的語言太麻煩了,相比較之下還是喜歡面嚮物件語言,不過慢慢地也體會到了C語言的樂趣,感覺還是在於解決問題的思路,語言是一種輔助的工具,選擇合適的語言有時候會方便很多。
關鍵程式碼
- 讀取檔案後,遍歷檔案的每一行,統計行數,字元數和詞數
//遍歷檔案的每一行,統計行數,字元數和詞數
fgets(st,bufsize,fp);
res.line++;
int len=strlen(st);
for (int i=0;i<len;i++)
{
if (is_character(st[i]))
{
res.character++;
if ( i==0 || !is_character(st[i-1]) )
res.word++;
}
}
2.程式碼行與空行的判斷
// 程式碼行與空行的判斷
int show_char=0;
for (int i=0;i<len;i++)
{
if (st[i]!=' ' && st[i]!='\n' && st[i]!='\t')
show_char++;
}
if (show_char>1) res.code_line++;
else res.null_line++;
3.註釋行的判斷
// 註釋行的判斷
bool is_annotation_line=false;
show_char=0;
for (int i=0;i<len;i++)
{
if ((st[i]!=' ') && st[i]!='\n' && st[i]!='\t')
{
show_char++;
if (st[i]=='/')
{
if (i+1<len && st[i+1]=='/')
is_annotation_line=true;
break;
}
if (show_char>1) break;
}
}
if (is_annotation_line==true) res.annotation_line++;
4.遞迴處理目錄下符合條件的檔案
//遞迴處理目錄下符合條件的檔案
void listFiles(string dir,Topt nowopt)
{
intptr_t handle;
_finddata_t findData;
handle = _findfirst((dir+"\\*.*").c_str(), &findData); // 查詢目錄中的第一個檔案
if (handle == -1)
{
cout << "Failed to find first file!\n";
return;
}
do
{
string nextdir=dir+'/'+string(findData.name);
if (strcmp(findData.name, ".") == 0) continue;
if (strcmp(findData.name, "..") == 0) continue;
if (findData.attrib & _A_SUBDIR )
{
listFiles(nextdir,nowopt);
}
else
{
printf("the file is %s\n",(nextdir).c_str());
int len=nextdir.size();
char filename[len+1];
nextdir.copy(filename, len, 0);//這裡5代表複製幾個字元,0代表複製的位置,
filename[len]='\0';
work(filename,nowopt);
printf("-------------\n");
}
} while (_findnext(handle, &findData) == 0); // 查詢目錄中的下一個檔案
_findclose(handle); // 關閉搜尋控制代碼
}
PSP
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 430 | 680 |
Estimate | 估計這個任務需要多少時間 | 30 | 30 |
Development | 開發 | 400 | 650 |
Analysis | 需求分析 (包括學習新技術) | 150 | 250 |
Design Spec | 生成設計文件 | 20 | 40 |
Design Review | 設計複審 (和同事稽核設計文件) | 20 | 30 |
Coding Standard | 程式碼規範 (為目前的開發制定合適的規範)劃 | 10 | 30 |
Design | 具體設計 | 30 | 40 |
Code Review | 程式碼複審 | 30 | 60 |
Test | 測試(自我測試,修改程式碼,提交修改) | 30 | 50 |
PReporting | 報告 | 110 | 150 |
Test Report | 測試報告 | 30 | 60 |
Size Measurement | 計算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事後總結, 並提出過程改進計劃 | 60 | 70 |
合計 | 計劃 | 430 | 680 |