個(gè)人可以自由轉(zhuǎn)載本文,,不過(guò)應(yīng)保持原文的完整性,并通知我,;商業(yè)轉(zhuǎn)載先請(qǐng)和我聯(lián)系,。 本文沒(méi)有任何明確或不明確地提示說(shuō)本文完全正確,閱讀和使用本文的內(nèi)容是您自己的選擇,,本人不負(fù)任何責(zé)任,,但是如果您發(fā)現(xiàn)本文有錯(cuò)漏的地方,,希望您可以給我指出。 本文假定您已經(jīng)對(duì)編程比較熟悉,,所以對(duì)一些本人認(rèn)為簡(jiǎn)單的問(wèn)題不會(huì)做太多的解釋?zhuān)绻惺裁磫?wèn)題,,可以給我提出。(如果您知道在 C++ Builder 中有現(xiàn)成的 Split 函數(shù),,請(qǐng)務(wù)必通知我,,謝謝) 意見(jiàn)、建議和提出的問(wèn)題最好寫(xiě)在我的主頁(yè) http://llf.126.com 的留言版上,。
最近,,對(duì) C++ Builder 比較感興趣了。因?yàn)樗?C ,,而 C 的移植性會(huì)好一些,,如果把在 Windows 平臺(tái)上開(kāi)發(fā)的程序移植到 Unix 上去的話,C 就比 VB 或者 Delphi 更具優(yōu)勢(shì),。當(dāng)然,,C++ Builder 是否還是純種的 C++ 不太好說(shuō),特別它還能同時(shí)編譯 Delphi 的程序,,好是好,,不過(guò)也讓人相信,我們使用的很多類(lèi)其實(shí)是繼承自 Delphi 的源代碼的,,這樣的話,,移植性又仍然不好了,不過(guò)不說(shuō)了,,因?yàn)樵谑褂弥邪l(fā)現(xiàn) C++ Builder 現(xiàn)有的類(lèi)非常不好用,,我想我大概會(huì)自己編寫(xiě)一套“純種”的 C++ 類(lèi)庫(kù),這樣的話就應(yīng)該不存在兼容性的問(wèn)題了,。 不說(shuō)這些了,,還是回到程序上來(lái)。有些習(xí)慣真的很難改掉,,比如我在處理字符串的時(shí)候,,每每都會(huì)希望使用 Split 、Join 這些函數(shù),,特別是 Split 函數(shù),,缺了它簡(jiǎn)直就如同斷了左膀右臂,干什么都不順手,,所以我的第一個(gè)目標(biāo)就是在 C++ Builder 中實(shí)現(xiàn) Split 函數(shù),。 要實(shí)現(xiàn) Split 函數(shù),第一個(gè)問(wèn)題和 VB 碰到的一樣,那就是 C++ Builder 能返回字符串?dāng)?shù)組嗎,?當(dāng)然,,這里說(shuō)的字符串?dāng)?shù)組不能單純的是一個(gè)指針,因?yàn)橐惨獜钠渲械玫綌?shù)組大小的數(shù)據(jù),,但是又不想多加一個(gè)參數(shù),,我們知道,C++ 確實(shí)可以返回對(duì)象指針,,那么現(xiàn)在的問(wèn)題就是:C++ Builder 中有現(xiàn)成的字符串?dāng)?shù)組類(lèi)嗎,? 參考了一些 Delphi 的教程,發(fā)現(xiàn) Delphi 里是有的,,叫做 TStrings ,,但是我在 C++ Builder 中使用的時(shí)候,編譯器告訴我 TStrings 是一個(gè)抽象類(lèi),,不能直接使用,,真是可惡,不明白為什么 TStrings 就是一個(gè)抽象類(lèi),,平白地浪費(fèi)了這么好的名字,。再搜查,找到了一個(gè) TStringList 類(lèi),,這是可以的,,所以第一個(gè)問(wèn)題解決了。 第二個(gè)問(wèn)題是 C++ Builder 中的字符串類(lèi),。察看了一下幫助,,字符串類(lèi)共有三種:ShortString 、AnsiString ,、WideString ,。ShortString 只能到 255 字節(jié),故不取,,而后兩種 AnsiString 表示 ANSI 字符串,,WideString 表示 UniCode 字串(關(guān)于 ANSI 字符串和 UniCode 字串的問(wèn)題可參見(jiàn)我的另一篇文章《VB 與 UniCode》),大家如果熟悉 UniCode 的話,,想必會(huì)和我一樣選擇 WideString 的,。 至此,應(yīng)該沒(méi)有問(wèn)題了,,不過(guò) WideString 又給我開(kāi)了一個(gè)不大不小的玩笑:可以使用其成員函數(shù) Pos 取得另一個(gè)字串在當(dāng)前字串中的位置,但是卻不能設(shè)定從哪里開(kāi)始查起,!于是我不得不在查到一個(gè)匹配之后就把原字串重新使用 SubString 賦值一次,,實(shí)在是可惡之極了,我想這一次在 C++ Builder 上實(shí)現(xiàn)的 Split 一定會(huì)比 VB 中的慢了,,不過(guò)想一想,,大概也不會(huì)用它處理太大的字串,,問(wèn)題倒也不大。 TStringList *Split(WideString Spliter, WideString String, int SplitNumber = 0) { int const MaxPos = 0x7fffffff, StartPos = 1; int FindPos, CharLen, Length, MySplitNumber=0; TStringList *Strs = new TStringList; BOOL LostTail; //if (SplitNumber == 0) LostTail = TRUE; 不嚴(yán)格,,LostTail 在 // SplitNumber != 0 時(shí)可能是任何值,。故修改如下: LostTail = (SplitNumber == 0); //^^^^^^^^^^^^^^^^^^^^^^^^^^\\ if (SplitNumber <= 0) SplitNumber = MaxPos; else MySplitNumber = SplitNumber; CharLen = Spliter.Length(); Length = String.Length(); while(1) { FindPos = String.Pos(Spliter); if (CharLen <= 0){ if (FindPos > Length) break; else FindPos++; } if ((FindPos == 0) || (SplitNumber <= 1)){ Strs->Add(String.SubString(StartPos,MaxPos)); break; } --SplitNumber; Strs->Add(String.SubString(StartPos,FindPos - StartPos)); String = String.SubString(FindPos+CharLen,MaxPos); } int i; for (i=Strs->Count; i<MySplitNumber; i++){ Strs->Add(""); } if (LostTail){ for (i = Strs->Count - 1; i>=0; i--) if (Strs->Strings[i] == "") Strs->Delete(i); else break; } return Strs; } 實(shí)現(xiàn)本身就沒(méi)有什么可說(shuō)的了,幾乎照搬我在 VB 中的實(shí)現(xiàn),,不過(guò)調(diào)用還是需要小心一些: //--------------------------------------------------------------------------- #define MsgBox(Text) MessageBox(this->Handle,Text,this->Caption.c_str(),MB_OK); #include "Perl2.cpp" //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { char Str4Split[] = "abc,123,uio,,,,"; TStringList *Strs; Strs = Split(",", Str4Split,-1); for (int i=0; i < Strs->Count; i++) { MsgBox(Strs->Strings[i].c_str()); } delete Strs; } //--------------------------------------------------------------------------- 如上,,定義變量時(shí)要使用“TStringList *Strs”,而在函數(shù)結(jié)束的時(shí)候,,一定要調(diào)用一下“delete Strs;”,,據(jù)說(shuō)不然會(huì)造成內(nèi)存泄漏,雖然不知道為什么這樣,,不過(guò)小心使得萬(wàn)年船,,聽(tīng)話就是了。 :-< 自我感覺(jué),,這一次實(shí)現(xiàn) C++ Builder 版的 Split 真是一種痛苦,,如果某一時(shí)刻我又需要使用它的 Variant 類(lèi),想必真的會(huì)被它給活活氣死的,! :) |
|
來(lái)自: quasiceo > 《待分類(lèi)1》