以'\n'來切割vector中的每一個容器元素多長。
(如果全部用一個CString,有時Buffer不足會導致錯誤)
檔案的讀取和儲存,則是使用MFC內建的CStdioFile,它的操作和標準C++處理檔案類別很像。
TxtFile.h
#ifndef TXTFILE_H
#define TXTFILE_H
#include <vector>
typedef std::vector<CString> TxtStrData;
class CTxtFile
{
CStdioFile ftxt_Std;
TxtStrData dtxt_Txt;
public:
CTxtFile(){};
virtual ~CTxtFile(){};
BOOL Open(LPCTSTR, CFileException&);
BOOL Save(LPCTSTR, CFileException&);
void Close(){ ftxt_Std.Close(); };
void iTxtData(TxtStrData& data){ dtxt_Txt = data; mem2file(); };
void oTxtData(TxtStrData& data){ file2mem(); data = dtxt_Txt; };
TxtStrData oTxtData(){ file2mem(); return dtxt_Txt; };
private:
void file2mem();
void mem2file();
void errorMsg(CFileException&);
};
#endif
TxtFile.cpp
檔案的讀寫
檔案讀寫,其實操作和C++原本的類別操作沒有兩樣。只是要特別設計的地方在於「發生錯誤」的處理方式,是不是可以馬上顯示出正確的錯誤訊息。
BOOL CTxtFile::Open(LPCTSTR path, CFileException& fx)
{
if (PathFileExists(path))
{
if (ftxt_Std.Open(path, CFile::modeRead | CFile::typeText, &fx))
return TRUE;
else
{
errorMsg(fx);
ftxt_Std.Close();
return FALSE; //失敗
}
}
else
return FALSE;
}
BOOL CTxtFile::Save(LPCTSTR path, CFileException& fx)
{
if (ftxt_Std.Open(path, CFile::modeCreate | CFile::modeWrite | CFile::typeText, &fx))
return TRUE;
else
{
errorMsg(fx);
ftxt_Std.Close();
return FALSE;
}
}
錯誤訊息的顯示
檔案做動作時,會出現的錯誤訊息void CTxtFile::errorMsg(CFileException& fx)
{
//例外處理
TCHAR buf[255];
fx.GetErrorMessage(buf, 255);
CString strPrompt;
strPrompt.Format("CTxtFile說:「%s」", buf);
AfxMessageBox(strPrompt);
}
資料從硬體到記憶體的動作
資料在記憶體中如何存放,會是檔案讀寫的一個重點。若格式太特殊,則此類別的再用率降低。反之亦然。
所以,在此就將這個設計規劃成獨立的function,可以再設計,讓source code的再用率做一個折衷。
在此設計的方式,是使用一個vector來儲存一整個純文字檔,以'\n'符號來做vector的每一個元素的分隔。巨觀來說就是純文字檔的每一行,存成每一個vector的元素,而每一個元素就是一個CString(MFC的字串)。每個字串的切割需求,可以用繼承的方式來利用這個類別的function。
void CTxtFile::file2mem()
{
dtxt_Txt.clear();
CString strTemp;
while (ftxt_Std.ReadString(strTemp))
{
strTemp.Format(_T("%s\n"), strTemp);
dtxt_Txt.push_back(strTemp);
}
}
void CTxtFile::mem2file()
{
if (!dtxt_Txt.empty())
{
for (TxtStrData::iterator it = dtxt_Txt.begin(); it != dtxt_Txt.end(); ++it)
//AfxMessageBox(*it);
ftxt_Std.WriteString(*it);
}
}