代碼下載見:http://download.csdn.net/source/2954182
前一周裡主要是針對標準C++和MFC融合編程做了一些試探性的工作,並將一些前期預先處理代碼由C#改成了C++。這回我要徹底地摒棄C#了,也可以安心用C++做畢設實驗了。
先上一張,展示下預先處理的部分工作。
總結:VS平台下,字串類型(string,wstring,char CString)容易引起混亂。這一點在寫代碼的時候一定要注意。
我採取的方案是:盡量讓自己的演算法不被VS平台所綁架,即除非用控制項顯示字字串,否則不用CString。
這樣就需要一個類專門用來處理各種字串之間的轉換。
在此定義為stringprocess類。
該類代碼如下:
char ,string ,wstring, Cstring之間的互相轉換
#include "StdAfx.h"
#include "stringprocess.h"
using namespace std;
stringprocess::stringprocess(void)
{
}
stringprocess::~stringprocess(void)
{
}
/************************************************************************/
/* 窄字串轉換成寬字元串 */
/************************************************************************/
wstring stringprocess:: myMultibyteToWideChar(string sResult)
{
int iWLen=MultiByteToWideChar( CP_ACP, 0, sResult.c_str(), sResult.size(), 0, 0 );// 計算轉換後寬字元串的長度。(不包含字串結束符)
wchar_t *lpwsz= new wchar_t [iWLen+1];
MultiByteToWideChar( CP_ACP, 0, sResult.c_str(), sResult.size(), lpwsz, iWLen ); // 正式轉換。
lpwsz[iWLen] = L'\0';
wstring wsResult(lpwsz);
delete []lpwsz;
return wsResult;
}
string stringprocess:: myWideCharToMultibyte(wstring wsResult)
{
string sResult;
int iLen= WideCharToMultiByte( CP_ACP, NULL, wsResult.c_str(), -1, NULL, 0, NULL, FALSE ); // 計算轉換後字串的長度。(包含字串結束符)
char *lpsz= new char[iLen];
WideCharToMultiByte( CP_OEMCP, NULL, wsResult.c_str(), -1, lpsz, iLen, NULL, FALSE); // 正式轉換。
sResult.assign( lpsz, iLen-1 ); // 對string對象進行賦值。
delete []lpsz;
return sResult;
}
CString stringprocess::stringToCString(string sResult)
{
CString cstrResult(sResult.c_str());
return cstrResult;
}
string stringprocess::CStringTostring(CString cstr)
{
return static_cast<LPCSTR>(CStringA(cstr));
}
void stringprocess:: CStringTochar(char* out,CString cstr)
{
int nLength = cstr.GetLength();
int nBytes = WideCharToMultiByte(CP_ACP,0,cstr,nLength,NULL,0,NULL,NULL);
char* P_char= new char[ nBytes+1];
memset(P_char,0,nBytes + 1);
WideCharToMultiByte(CP_OEMCP, 0, cstr, nLength, P_char, nBytes, NULL, NULL);
memcpy(out,P_char,nBytes+1);
}
void stringprocess::TrimString(string &str,const string val)
{
str.erase(0,str.find_first_not_of(val));
str.erase(str.find_last_not_of(val)+val.size());
}
string stringprocess:: do_fraction(int value)
{
ostringstream out;
//int prec=numeric_limits<int>::digits10; // 18
//out.precision(prec);//覆蓋預設精度
out<<value;
string str= out.str(); //從流中取出字串
str.swap(string(str.c_str()));//刪除nul之後的多餘字元
return str;
}
另外,要保持核心演算法(儘管在碩士論文中不可能有什麼破天荒的獨創性核心演算法,姑且這麼叫吧)的可移植性。核心演算法要自己定義成一個類進行封裝,萬萬不可和MFC架構類混在一起。記住MFC僅用於結果顯示。比如,在"搜尋"按鈕的單擊函數中,我們查詢資料庫,顯示結果。我們把查詢資料庫也看做是核心演算法的一部分,因此資料庫查詢代碼不直接出現在按鈕的單擊函數中。
如下:
代碼
void CTabPage1Dlg::OnBnClickedBtnsearch()
{
stringprocess strp;
RoughAnalyzer analyzer;
vector<string> retword;
vector<pair<string,string> >retconcept;
UpdateData();
//MessageBox(m_editstring);
CString selectcstr;
CString cstrselectconcept;
if (m_editstring.GetLength()==1)
{
selectcstr.Format(_T("select num, define from liuyuwordlist where characters='%s' and class='ZI'"),m_editstring);
}
else
{
selectcstr.Format(_T("select num, define from liuyuwordlist where words='%s'"),m_editstring);
}
string selectstr=strp.CStringTostring(selectcstr);
cstrselectconcept.Format(_T("select name,defdesc from concept where name like'%s[_]%%'"),m_editstring);
string strselectconcept=strp.CStringTostring(cstrselectconcept);
analyzer.GetFromDataBaseByWord(retword,selectstr);
analyzer.GetFromConceptByWord(retconcept,strselectconcept);
m_ListCtrl.DeleteAllItems();
m_listCtrl2.DeleteAllItems();
int i=0;
int j=0;
for (vector<string>::iterator it=retword.begin();it!=retword.end();it++)
{
CString cstrtmp=strp.stringToCString(*it);
m_ListCtrl.InsertItem(i,m_editstring);
m_ListCtrl.SetItemText(i,1,cstrtmp);
i++;
}
for (vector<pair<string,string>>::iterator it=retconcept.begin();it!=retconcept.end();it++)
{
CString cstrpart1=strp.stringToCString(it->first);
CString cstrpart2=strp.stringToCString(it->second);
m_listCtrl2.InsertItem(j,cstrpart1);
m_listCtrl2.SetItemText(j,1,cstrpart2);
j++;
}
// TODO: Add your control notification handler code here
}