uniqコマンド ? の製作
とりあえずuniqフィルタ通すだけのためにVMwareでOpenBSD起動するのもアレなんで uniq作成中...w
mfcよく分からんな...
結構使ってるけどダイアログモードだったり、CWndだったりするのできちんとSDI MDI使ったことないw
ON_COMMAND(ID_UNIQ, OnUniq)
void CuniqApp::OnUniq()
{
CString temp;
CEditView* ev = (CEditView*)((CFrameWnd*)AfxGetMainWnd())->GetActiveView();
ev->GetEditCtrl().GetWindowText(temp);
これでツールバーのクリックでCuniqApp::OnUniq()が呼ばれる
で、アクティヴなビューから
tempをパースする.... どーすっかなー strtokかけたろかwww
CStringを改行でパースしてCStringArray に投げ込む。
素直にMFC CStringで書いた
たぶんこっちのほうがオーバヘッド少なめだと想う。
Left Rightは実装的に自メンバのカウント操作してるだけだし。
*1
バッファ不足で落ちるから作り直したわー
CString 再帰かけるとムリダナ(・×・)
http://d.hatena.ne.jp/ore_de_work/20130223#1362403125
void ParseLines(CStringArray &sa, CString& doc) { int loc, roc; if ( (loc = doc.Find(_T("\n"))) != -1 ) { // LF roc = loc + 1; if(doc.Left(loc).Right(1) == _T('\r')) { // CRLF loc = loc - 1; } sa.Add(doc.Left(loc)); doc = doc.Right(doc.GetLength() - roc); ParseLines(sa, doc); } else if ( (loc = doc.Find(_T("\r"))) != -1 ) { // CR only roc = loc + 1; sa.Add(doc.Left(loc)); doc = doc.Right(doc.GetLength() - roc); ParseLines(sa, doc); } else { // only line. sa.Add(doc); doc = _T(""); } }
再帰したらあかんわー
uniq実装部分
// CuniqApp メッセージ ハンドラ void CuniqApp::OnUniq() { // parse int i; CStringArray satemp; CStringArray sauniq; CString temp; CString newtext; CEditView* ev = (CEditView*)((CFrameWnd*)AfxGetMainWnd())->GetActiveView(); ev->GetEditCtrl().GetWindowText(temp); ParseLines(sauniq, temp); //uniq if( sauniq.GetCount() > 0 ) { temp = sauniq[0]; satemp.Add(sauniq[0]); for(i=1;i<sauniq.GetCount();i++){ if(temp != sauniq[i]){ temp = sauniq[i]; satemp.Add(sauniq[i]); } } // store for(i=0;i<satemp.GetCount();i++){ newtext += satemp[i]; if( i != satemp.GetCount() -1 ) newtext += _T("\r\n"); } ev->GetEditCtrl().SetWindowText(newtext); } }
さらに少し変更した。
所詮ニンゲンが読む程度のテキストファイルだしquicksortはいらんよね.
と想ったけど、やっぱquicksortにしたwww
CSortStringArray のソースは
http://support.microsoft.com/kb/120961
にあるのをコペピ
quick の場合は、http://support.microsoft.com/kb/216858/ja
// ダイアログを実行するためのアプリケーション コマンド void CuniqApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } void ParseLines(CStringArray &sa, CString& doc) { int loc, roc; if ( (loc = doc.Find(_T("\n"))) != -1 ) { // LF roc = loc + 1; if(doc.Left(loc).Right(1) == _T('\r')) { // CRLF loc = loc - 1; } sa.Add(doc.Left(loc)); doc = doc.Right(doc.GetLength() - roc); ParseLines(sa, doc); } else if ( (loc = doc.Find(_T("\r"))) != -1 ) { // CR only roc = loc + 1; sa.Add(doc.Left(loc)); doc = doc.Right(doc.GetLength() - roc); ParseLines(sa, doc); } else { // only line. sa.Add(doc); doc = _T(""); } } _AFXEXT_INLINE CEdit& CuniqApp::GetEditCtrl() const { CEditView* ev = (CEditView*)((CFrameWnd*)AfxGetMainWnd())->GetActiveView(); return ev->GetEditCtrl(); } void CuniqApp::StoreStringArray(CStringArray& sa) { INT_PTR i; CString newtext; for(i=0;i<sa.GetCount();i++){ newtext += sa[i]; if( i != sa.GetCount() -1 ) newtext += _T("\r\n"); } GetEditCtrl().SetWindowText(newtext); } // CuniqApp メッセージ ハンドラ void CuniqApp::OnSelectall() { GetEditCtrl().SetSel(0,-1,0); } void CuniqApp::OnUniq() { INT_PTR i; CStringArray sauniq; CString temp; CStringArray satemp; GetEditCtrl().GetWindowText(temp); ParseLines(sauniq, temp); //uniq if( sauniq.GetCount() > 0 ) { temp = sauniq[0]; satemp.Add(sauniq[0]); for(i=1;i<sauniq.GetCount();i++){ if(temp != sauniq[i]){ temp = sauniq[i]; satemp.Add(sauniq[i]); } } StoreStringArray(satemp); } } void CuniqApp::OnSort() { CSortableStringArray sa; CString temp; GetEditCtrl().GetWindowText(temp); ParseLines(sa, temp); sa.Sort(); StoreStringArray(sa); } void CuniqApp::OnReverseSort() { CSortableStringArray sa; CString temp; GetEditCtrl().GetWindowText(temp); ParseLines(sa, temp); sa.Sort(CSortableStringArray::Reverse); StoreStringArray(sa); } void CuniqApp::OnReverse() { INT_PTR i; CStringArray sa; CStringArray reverse; CString temp; GetEditCtrl().GetWindowText(temp); ParseLines(sa, temp); for(i=sa.GetCount() -1;i>=0;i--){ reverse.Add(sa[i]); } StoreStringArray(reverse); }
しかし継承効いてるとそのままパース関数に食わせれるのが美味しいなw
Cでもできるだろうけど、無理矢理キャストしないとだめだしw
*1:Splitだと、\r \n 混在に対応できない、というか古いのでCString::Split なんてないです。AfxExtractSubString つかうらしい