⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 判斷一個字是否為big-5中文字? (2001年4月23日).txt

📁 自己对DELPHI学习的一点体会
💻 TXT
字号:
判斷一個字是否為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()就可以了吧. 


 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -