delphi 编程技巧

源代码在线查看: 判斷一個字是否為big-5中文字? (2001年4月23日).txt

软件大小: 774 K
上传用户: zyhunicom
关键词: delphi 编程技巧
下载地址: 免注册下载 普通下载 VIP

相关代码

				判斷一個字是否為BIG-5中文字? (2001年4月23日) 
				
				网友更新  分类:杂类   作者: zhuhongqing(推荐)  推荐:zhuhongqing   阅读次数:221  
				(http://www.codesky.net)  
				
				--------------------------------------------------------------------------------
				假如沒有中文應用組件的朋友, Win32 中有一個 IsDBCSLeadByte 這個 API 可用, 在 Delphi 的使用示例如下: 
				
				Windows.IsDBCSLeadByte(byte(sTest[1])); 
				
				(中文應用組件中的 IsLeadByte 其實也只是呼叫這個 API 而已) 
				
				就連是不是中文字這樣簡單的問題可能都並不單純喔...., 這個問題之前被我想得有點鑽牛à尖了.... 也許原發問者寬達可以將 C 的程式借我看一下... :p 
				
				先來看這個例子: 
				
				procedure TForm1.Button5Click(Sender: TObject); 
				var 
				sTest: string; 
				begin 
				sTest := '中文字'; 
				// 沒有應用組件的請用這個: Windows.IsDBCSLeadByte(byte(sTest[1])); 
				if IsLeadByte(@sTest[1]) then ShowMessage('Yes 1'); 
				if IsLeadByte(@sTest[2]) then ShowMessage('Yes 2 ???'); 
				end; 
				Yes1 顯示出來是對的, 可是 Yes2 也跑出來, 就..., 看來, 這個IsDBCSLeadByte可能只比對了一下內碼表就給結果了. 所以, 以下的程式: 
				
				procedure TForm1.Button1Click(Sender: TObject); 
				var 
				s: string; 
				i: integer; 
				begin 
				s := '中文字'; 
				for i := 1 to Length(s) do 
				if Windows.IsDBCSLeadByte(byte(s[i])) then 
				ShowMessage(IntToStr(i) + '*' + IntToStr(Ord(s[i]))); 
				end; 
				1. 2. 3. 4. 5. 都是 Leadbyte, 連 TrailByte 也是..., 哈哈! 
				
				當然, 這牽到中文字是 double-byte, 既然只判斷一個位置不準, 就有人利用兩個字元指標, 除了本身之外, 還比較參考另一個位置的字元, 然後得出一個比較準確的結果. 有興趣的朋友可以參考中文應用組件的以下兩個函數: 
				
				function IsMBSLead( p1, p2: pchar ) : Boolean; 
				function IsMBSTrail( p1, p2: pchar ) : Boolean; 
				它們可能比較準一些. 
				
				大家可能曾注意過, Windows 95 的 EditBox 並無法以滑鼠對半個中文字作出反白選擇標記, 所以, 我自以為找到一個很慢但準確的方法, 可是以下的情形呢? 
				
				procedure TForm1.Button2Click(Sender: TObject); 
				{$h-} 
				var 
				sTest: string; 
				begin 
				sTest := '中文字'; 
				ShowMessage(Copy(sTest, 2, 2)); 
				with TEdit.Create(Self) do 
				begin 
				Parent := Self; 
				// Text := Copy(sTest, 2, 2); // 1. 中?? bug 
				Text := sTest[2] + sTest[3]; // 2. 中?? bug 
				// 不要懷疑, TrailByte + 另一個字的 Leadbyte 正好是 '中' 
				// 不是 Copy 函數有問題 
				SelStart := 0; 
				SelLength := 2; 
				if SelLength = 0 then ShowMessage('Not Chinese') 
				else ShowMessage('Yes, Chinese word'); 
				Free; 
				end; 
				end; 
				沒錯啦! 結果是'中'字, 判斷'中'字是中文字也對, 但是各拆一個字的前後出來組出來的結果再判斷其一個字元是不是Leadbyte, 簡直是GIGO (Garbage In Garbage Out)的典型. 
				
				說了半天, 問題被我複雜化了, 簡單的說, 
				
				1. IsDBCSLeadByte 不是一可完全可靠的函數, 中文是 double-byte, 只以一個傳入字元值作判斷常常不準. 
				2. 要正確將各個中文字斷開的程式可能很複雜. 用兩個 pchar 來作比較, 準確性會提高一點. 
				
				只是提高一點而已, 有中文應用組件的朋友可以試試: 
				
				var 
				sOrigin, sTest: string; 
				begin 
				sOrigin := '中文字'; 
				sTest := Copy(sOrigin, 4, 2); // 變成 憒 這個怪字 
				if IsMBSLead(@sTest[1], @sTest[1]) then Showmessage('Leadbyte'); 
				end; 
				對的, 我又故意切開中文, 所以有人會講, 應該是 Copy(..., 3, 2)才是, 嗯! ê我怎麼知道該從哪裏開始呢?(哪裏是中文字)? 唉! 我腦筋又不清楚了... 
				
				中文應用組件有 AnsiCopy() 視中文字為一個單位, ê以下的程式呢? 
				
				var 
				sTest: string; 
				begin 
				sTest := '中文字'; 
				ShowMessage(AnsiCopy(sTest, 2, 2)); 
				sTest := #156 + '中文字'; 
				ShowMessage(AnsiCopy(sTest, 2, 2)); // ??中憒.. 
				end; 
				講了這麼多, 我的意見是: 回到原點, 除非有人故意搗蛋或者傳入的字串已經有問題, 或者ê個內碼根本沒有字, 否則只用IsDBCSLeadByte()就可以了吧. 
				
				
				 
				 
							

相关资源