'冬瓜湯編寫整理 字符串處理,對于大部分語言來說,都是一件麻煩的事,ansi,unicode,utf-8……,我前面已經(jīng)說過了,F(xiàn)B對于unicode支持不是特別的好,也就是wstring只能是指針或固定長度,而不是動態(tài)不定長的字符串,這非常麻煩。雖然wstr()可以快速將string字符串轉(zhuǎn)變成wstring字符串,但其實(shí)很多場合下的使用,還是非常不方便。afx的CWstr類就是專門處理unicode字符串,其實(shí)用它可以處理ansi,unicode,utf-8,Bstr(vbstring),非常方便,不管是網(wǎng)絡(luò)上常用的utf-8,還是com的BSTR,都挺方便的。 一、len(),和sizeof()對字符串的影響 在FB中,len()用來判斷一個(gè)字符串的大小, 對于string和zstring來說,len返回的是字節(jié)大小。對于unicode來說,len()返回的是字符數(shù)。uniocde字符串的字節(jié)大小,是len(unicode)*2 。 而sizeof()是用來判斷一個(gè)變量,對象內(nèi)存占用多少。 這是一個(gè)測試?yán)樱? #include once "afx/cwindow.inc" Dim As String anStr,anStrEN dim anStrU as string dim unStr as wstring*20 '這里直接用固定長度20個(gè)unicode字符 anStrEn = "FB is new basic" unstr = "FB是語言" anstr = "FB是語言" anStrU = wstr(anstr) afxmsg "ansi的Len大。" Len( anstr) chr(13) _ "ansi的sizeof大小:" sizeof(anstr) chr(13) _ "ansi純英文的Len大。" Len( anstrEn) chr(13) _ "ansi純英文的sizeof大小:" sizeof(anstrEn) chr(13) _ "unicode的Len大。" len(unStr) chr(13) _ "uniocde的sizeof大。" sizeof(unStr) chr(13) _ "an轉(zhuǎn)Un的len大小:" len(anStrU) chr(13) _ "an轉(zhuǎn)Un的sizeof大。" sizeof(anStrU) chr(13) _ "wstr()返回值的Len大小:" len(wstr(anstr)) chr(13) _ "wstr()返回值的sizeof大。" sizeof(wstr(anStr)) 在這里我們會發(fā)現(xiàn)sizeof對于string不起作用,總是返回大小12,這我無法解釋,只能把它理解成因?yàn)閟tring是一個(gè)動態(tài)不定長的字符串?dāng)?shù)組,sizeof返回的實(shí)際上是一個(gè)數(shù)組結(jié)構(gòu)的字節(jié)大小。如果用64位編譯,你會發(fā)現(xiàn)sizeof總是返回24。 (2)wstr(string)賦值給一個(gè)string類型的變量,不會發(fā)現(xiàn)任何變化。 (3) sizeof(wstr())總是返回0,估計(jì)是一個(gè)Null值。 所以在實(shí)際使用中如果要預(yù)先分配內(nèi)存的話,千萬要小心不要誤以為sizeof(string)能返回總字節(jié)大小。 '冬瓜湯整理編寫 二、使用afx的字符串函數(shù) #include once "afx/CWSTR.inc" #include once "afx/afxStr.inc" using afx ' 所有的afx庫,都處在同一個(gè)命名空間afx里,F(xiàn)B的命名空間規(guī)則和c#/vb.net是一樣的。 '我不喜歡using這個(gè)關(guān)鍵詞,我更喜歡Imports,但沒辦法 import在FB很早以前就是一個(gè)關(guān)鍵字了。 '判斷是否是數(shù)字 Dim inNumeric As boolean=afxIsNumeric("-1395.43") '同left的用法 Dim As cwstr strLeft=afxstrClipLeft("這是一個(gè)Freebasic測試",9) '同mid的用法 Dim As cwstr strMid=afxstrClipMid("這是一個(gè)Freebasic測試",4,5) '同Right用法 Dim As cwstr strRight=afxstrClipRight("這是一個(gè)Freebasic測試",2) '左右嵌入空格或指定的符號 Dim As cwstr strCset=afxstrCset("單身狗",11,"*") '返回 ****單身狗**** '刪除指定數(shù)量的子字符串 Dim As cwstr strDelete=afxstrDelete("這是一個(gè)Freebasic測試",4,9) '從主字符串提取匹配指定字符的字符串,但不包括指定字符本身 Dim As cwstr strExtract=afxstrExtract(1,"誰是單身狗,不是單身貓","狗") ' Dim As cwstr strExtractAny=afxstrExtractAny(1,"誰是單身狗,不是單身貓","貓狗") '從指定位置插入子字符串 Dim As cwstr strInsert=afxstrInsert("01032547891","—",3) '從第三個(gè)位置之后插入子字符串 '同join用法 Dim cwsa As cwstrArray=cwstrArray(4,1) '建一個(gè)4行1列的數(shù)組 cwsa.Item(1) = "One" cwsa.Item(2) = "Two" cwsa.Item(3) = "Three" cwsa.item(4)="Four" DIM strJoinAS CWSTR = AfxStrJoin(cwsa, ",") '用法和vb的join一樣 '左邊加入指定數(shù)量的空格或指定符號 DIM strLset AS CWSTR = AfxStrLSet("FreeBasic", 20, "#") '解析帶分隔符的字符串,分隔符可以多種混用 DIM cws AS CWSTR = AfxStrParse("one,two,three", 2) ' Returns "two" DIM cws AS CWSTR = AfxStrParseAny("1;2,3", 2, ",;") ' Returns "2" '解析帶分隔符的字符串,并返回?cái)?shù)量 DIM nCount AS LONG = AfxStrParseCount("one,two,three", ",") ' Returns 3 DIM nCount AS LONG = AfxStrParseCountAny("1;2,3", ",;") ' Returns 3 '返回子字符串第一次出現(xiàn)在主字符串位置之前的那部分字符串,可以指定搜索位置從哪里開始,默認(rèn)從1 DIM cws AS CWSTR = AfxStrRemain("Brevity is the soul of wit", "is ") ' Returns "the soul of wit" DIM cws AS CWSTR = AfxStrRemainAny("I think, therefore I am", ",") ' Returns "therefore I am" '從主字符串移除子符串 DIM cws AS CWSTR = AfxStrRemove(" ", "[]") ' Returns "Hello" DIM cws AS CWSTR = AfxStrRemoveAny("abacadabra", "bac") ' Returns "dr" '替換,同Replace() DIM cws AS CWSTR = AfxStrReplace("Hello World", "World", "Earth") ' Returns "Hello Earth" DIM cws AS CWSTR = AfxStrReplaceAny("abacadabra", "bac", "*") ' Returns "*****d**r* '去掉主字符串不匹配指定的子符串的那部分,只返回匹配的子符串或子符串組 DIM cws AS CWSTR = AfxStrRetain("abacadabra","b") ' Returns "bb" DIM cws AS CWSTR = AfxStrRetainAny("1234567890ak;lk;l1234567890", ";/p") ' Returns ";;" '反轉(zhuǎn)字符串 DIM cws AS CWSTR = AfxStrReverse("garden") ' Returns "nedrag" '右邊添加指定數(shù)量的空格或指定符號 DIM cws AS CWSTR = AfxStrRSet("FreeBasic", 20, "*") '將帶各種不規(guī)范分隔符的字符串,整理成一種規(guī)范的字符串 DIM cws AS CWSTR = AfxStrShrink(",,, one , two three, four,", " ,")' Returns "one two three four" '同split DIM cws AS CWSTR = "- This, a sample string." DIM cwsa AS CWstrArray = AfxStrSplit(cws, " ,.-") FOR i AS LONG = cwsa.LBound TO cwsa.UBound PRINT cwsa.Item(i) NEXT '統(tǒng)計(jì)子符串在主子符串出現(xiàn)的次數(shù) DIM nCount AS LONG = AfxStrTally("abacadabra", "ab") ' Returns 2 DIM nCount AS LONG = AfxStrTallyAny("abacadabra", "bac") ' Returns 8 '在開頭和結(jié)尾,刪除成對的字符符號 AfxStrUnWrap("Paul", "", "") results Paul AfxStrUnWrap("'Paul'", "'") results Paul '確定主字符串是否包含指定子符串中任一一個(gè)字符 DIM nCount AS LONG = AfxStrVerify(5, "123.65,22.5", "0123456789") ' Returns 7 '在字符串開頭和結(jié)尾添加 成對的字符 AfxStrWrap('保羅',"", "")結(jié)果保羅 ……還有一些函數(shù),具體看幫助文檔 ########################################################### 三、使用BSTR 為了方便使用,我將Cbstr類和Cwstr類合并在同一個(gè)文件cwstr.inc中 #include once "afx/Cwstr.inc" using afx Dim myBstr as CBSTR myBstr="這是一個(gè)測試" 用 Cbstr類,主要是為了能夠自動釋放vbstring指針。忘記釋放bstr指針,是非常容易犯的錯(cuò)。所以一遇到任何傳進(jìn)來的bstr字符串 就立即用cbstr進(jìn)行接收。
'冬瓜湯改編自c語言中文網(wǎng)的c語言基礎(chǔ)入門 宏定義是預(yù)處理命令的一種,它允許用一個(gè)標(biāo)識符來表示一個(gè)字符串。 先看一個(gè)例子: #define N 100 dim sum as long sum=20 +N print Sum 運(yùn)行結(jié)果: 120 該示例中的語句 sum = 20 + N;,N被100代替了。 #define N 100就是宏定義,N為宏名,100是宏的內(nèi)容。 在編譯預(yù)處理時(shí),對程序中所有出現(xiàn)的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開”。 宏定義是由源程序中的宏定義命令#define完成的,宏代換是由預(yù)處理程序完成的。 宏定義的一般形式為: #define 宏名 字符串 #表示這是一條預(yù)處理命令,所有的預(yù)處理命令都以#開頭。define是預(yù)處理命令。宏名是標(biāo)識符的一種,命名規(guī)則和標(biāo)識符相同。字符串可以是常數(shù)、表達(dá)式等。 這里所說的字符串是一般意義上的字符序列,不要和FB語言中的字符串等同,它不需要雙引號。 程序中反復(fù)使用的表達(dá)式就可以使用宏定義,例如: #define M (n*n+3*n) 它的作用是指定標(biāo)識符M來代替表達(dá)式(y*y+3*y)。 在編寫源程序時(shí),所有的(y*y+3*y)都可由M代替,而對源程序編譯時(shí),將先由預(yù)處理程序進(jìn)行宏代換, 即用(y*y+3*y)表達(dá)式去替換所有的宏名M,然后再進(jìn)行編譯。 將上面的例子補(bǔ)充完整: 上面的程序中首先進(jìn)行宏定義,定義M來替代表達(dá)式(n*n+3*n),在sum=3*M+4*M+5*M中作了宏調(diào)用。在預(yù)處理時(shí)經(jīng)宏展開后該語句變?yōu)椋?sum=3*(n*n+3*n)+4*(n*n+3*n)+5*(n*n+3*n); 需要注意的是,在宏定義中表達(dá)式(n*n+3*n)兩邊的括號不能少,否則會發(fā)生錯(cuò)誤。 如當(dāng)作以下定義后: #difine M n*n+3*n在宏展開時(shí)將得到下述語句: s=3*n*n+3*n+4*n*n+3*n+5*n*n+3*n;這相當(dāng)于: 3n2+3n+4n2+3n+5n2+3n 這顯然是不正確的。所以進(jìn)行宏定義時(shí)要注意,應(yīng)該保證在宏代換之后不發(fā)生錯(cuò)誤。 對宏定義的幾點(diǎn)說明 1) 宏定義是用宏名來表示一個(gè)字符串,在宏展開時(shí)又以該字符串取代宏名,這只是一種簡單的替換。 字符串中可以含任何字符,可以是常數(shù),也可以是表達(dá)式,預(yù)處理程序?qū)λ蛔魅魏螜z查, 如有錯(cuò)誤,只能在編譯已被宏展開后的源程序時(shí)發(fā)現(xiàn)。 2) 宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起替換。 3) 宏定義必須寫在函數(shù)之外,其作用域?yàn)楹甓x命令起到源程序結(jié)束。如要終止其作用域可使用#undef命令。例如: #define PI 3.14159 Sub main () ' Code return 0 ; end Sub #undef PI Function func () 'Code end Function '========================= 表示PI只在main函數(shù)中有效,在func中無效。 4) 宏名在源程序中若用引號括起來,則預(yù)處理程序不對其作宏代換,例如: #define OK 100 print "OK " 運(yùn)行結(jié)果: OK 該例中定義宏名OK表示100,但在 print 語句中 OK 被引號括起來,因此不作宏代換,而作為字符串處理。 5) 宏定義允許嵌套,在宏定義的字符串中可以使用已經(jīng)定義的宏名,在宏展開時(shí)由預(yù)處理程序?qū)訉哟鷵Q。例如: #define PI 3.1415926 #define S PI*y*y /* PI是已定義的宏名*/ 對語句: print S在宏代換后變?yōu)椋? print 3.1415926*y*y 6) 習(xí)慣上宏名用大寫字母表示,以便于與變量區(qū)別。但也允許用小寫字母。 7) 可用宏定義表示數(shù)據(jù)類型,使書寫方便。例如: #define UINT ULong 在程序中可用UINT作變量說明: dim as uint a, b 應(yīng)注意用宏定義表示數(shù)據(jù)類型和用type…… As定義數(shù)據(jù)說明符的區(qū)別。 宏定義只是簡單的字符串代換,是在預(yù)處理完成的,而type… As是在編譯時(shí)處理的,它不是作簡單的代換,而是對類型說明符重新命名。被命名的標(biāo)識符具有類型定義說明的功能。 宏定義雖然也可表示數(shù)據(jù)類型, 但畢竟是作字符代換。在使用時(shí)要分外小心,以避出錯(cuò)。