1.Github鏈接
GitHub鏈接地址https://github.com/Zzwenm/PersonProject-C2
2.PSP表格
| PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
|---|---|---|---|
| Planning | 計划 | ||
| • Estimate | • 估計這個任務需要多少時間 | 480 | 720 |
| Development | 開發 | ||
| • Analysis | • 需求分析 (包括學習新技術) | 120 | 180 |
| • Design Spec | • 生成設計文檔 | 30 | 40 |
| • Design Review | • 設計復審 | 40 | 60 |
| • Coding Standard | • 代碼規范 (為目前的開發制定合適的規范) | 30 | 20 |
| • Design | • 具體設計 | 40 | 60 |
| • Coding | • 具體編碼 | 150 | 180 |
| • Code Review | • 代碼復審 | 120 | 180 |
| • Test | • 測試(自我測試,修改代碼,提交修改) | 60 | 90 |
| Reporting | 報告 | ||
| • Test Repor | • 測試報告 | 60 | 40 |
| • Size Measurement | • 計算工作量 | 20 | 30 |
| • Postmortem & Process Improvement Plan | • 事后總結, 並提出過程改進計划 | 30 | 30 |
| 合計 | 700 | 910 |
3.計算模塊接口的設計與實現過程
/*定義words用於記錄單詞數量*/
typedef struct {
string word;
int num;
}words;
/*定義一個容量用於存單詞,方便后續的單詞排序*/
vector<words> v;
/*定義類File記錄.txt文件的信息*/
class File {
private:
int character; //字符數
int word; //單詞數
string filename; //文件名
public:
File();
File(string s); //通過命令行傳參獲取filename
void get_character();
void get_word();
void get_mostword();
void get_all();
};
/*分別統計字符數、統計單詞數和統計最多的10個單詞及其詞頻*/
程序通過命令行傳參獲取.txt文件記錄到filename中便於成員函數使用讀取文件。在調用成員函數統計時直接將字符數、單詞數記錄到file中,單詞及單詞出現個數記錄到words中並存入容量v中。
基本功能:
1.統計字符數
直接讀取文件每個字符記錄即可
file >> noskipws;// 記錄所有字符
file >> temp;
while (!file.eof())
{
character++;
file >> temp;
}
2.統計單詞數
由於單詞有規定:至少以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫。
所以需要對文件內容進行篩選,將每個字符連接起來記錄到string s中char a[2] = { temp,0 };s += temp;,在每遇到一個分隔符進行一次篩選。判斷單詞長度是否超過三,且前四個字符要都為英文字母,符合條件則到容量v中查找是否有相同單詞並記錄次數。一直讀取到文件末尾即可。
3.統計文件的有效行數:任何包含非空白字符的行,都需要統計。
設立一個變量用於統計每行非空白字符是否為零即可,非零即為有效行數。
4.統計文件中各單詞的出現次數,最終只輸出頻率最高的10個。頻率相同的單詞,優先輸出字典序靠前的單詞。
在統計單詞數時已經存到了容量v中,進行一次排序即可。可以利用sort函數對單詞進行排序。
sort(v.begin(), v.end(), set_word);set_word為bool函數用於比較順序
bool set_word(const words &a, const words &b) { if (a.num == b.num)return a.word<b.word;else return a.num>b.num; }
4.計算模塊接口部分的性能改進
由於第一步實現基本功能時沒有對基本功能進行分離,全部寫在了同一部分中,所以需要從中分離出,刪除掉沒用的部分。字符統計可以直接提取出來寫成一個函數,統計單詞時只需要將字符統計部分刪除掉結合class file統計即可。
5.計算模塊部分單元測試展示。
TEST_METHOD(TestMethod1)
{
// TODO: 在此輸入測試代碼
myFile file("in.txt");
Assert::AreEqual(745,file.get_characters());
}
TEST_METHOD(TestMethod2)
{
// TODO: 在此輸入測試代碼
myFile file("in.txt");
Assert::AreEqual(72, file.get_words());
}
TEST_METHOD(TestMethod3)
{
// TODO: 在此輸入測試代碼
myFile file("in.txt");
Assert::AreEqual(11, file.get_lines());
}
測試出現問題失敗了

經過多次測試發現將pch.cpp中的函數寫在pch.h中就不會有報錯。
上網查閱資料后發現在測試的cpp中加入
#include"../wordCount/pch.h"
#include"../wordCount/pch.cpp"
就可以解決問題。
Assert::AreEqual(2230243,file.get_characters());// 測字符數
Assert::AreEqual(232213, file.get_words());//測單詞數
Assert::AreEqual(15744, file.get_lines());//測有效行數

測試


計算模塊部分異常處理說明。
ifstream file(filename);
//添加錯誤提示說明 在讀取文件失敗時提示
if (!file)
{
cerr << "open error!" << endl;
exit(1);
}

感想
這次的代碼及封裝很早就完成實現了,大部分內容都需要在網上查閱資料學習,讀取文件,輸出文件,讀取文件中的字符,單詞的字典排序都需要上網學習一下,不過內容比較簡單,很快就完成了。在封裝的時候,由於個人的習慣,一直以來都沒有面向對象的習慣,所以都將代碼寫在了main()函數中,所以在分離封裝時又耗費了很久。同時也讓我學會在編程時要學會封裝接口,方便簡潔。在弄單元測試時,新建測試時弄了預編譯頭,出現了意外的錯誤,上網查找了解決辦法,修改了設置,弄得連最基本的調試都不能完成了。在修復后重新編寫單元測試還是遇到這個問題,沒有完成單元測試。在后續經過多次測試,終於找到了解決方法,也算是收獲了單元測試。
