Wolfgang Chien's Homepage | Delphi學習筆記 - 問答篇 |
各位先進!!
我嘗試將一個長字串,內含中文字及半形字,截剪成固定長度的字串如何能避免截剪到中文字,而出現亂碼?
您可以參考本信舉出的例子, 重點在於切出來的字串, 如何判定其最後一個字元是否是一個中文字的前半字.
我採用的是從頭檢視到最後的演算法, 也許有人會懷疑 --
![]() |
1. 為什麼不直接抓最後一個字元判斷? 因為中文字的 Trail-byte, 其內碼也可能落在 Lead-byte 的內碼區間內. |
![]() |
2. 為什麼不直接抓最後兩個字元來判斷? 因為前一個字的 Trail-byte 加上後一個字的 Lead-byte, 可能又是一個中文字. |
以上的考慮是基於DelphiChat以前討論過「判斷一個字是否為 BIG-5 中文字?」的討論, 判斷時的採用的方法與可能的問題我在此就不重覆了, 請大家自行參閱.
如果是 Win3.1, 11/25 robin <robin@eagle.com.tw>曾發表筆劃計算函數, 其中的中文字判斷不是用 IsDBCSLeadByte, 而是檢查內碼區間, 也一併建議給您參考. (下載 Robin 的筆劃計算函數)
![]() |
1. 在 form 上放置兩個 TMemo 元件, 一個 TButton |
![]() |
2. Button1 的 OnClick 事件.
procedure TForm1.Button1Click(Sender: TObject); const _LengthPerLine = 6; var i: integer; sLine: string; sCuted: string; iCutLength: integer; j: integer; bIsDBCS: boolean; begin if _LengthPerLine < 2 then Exit; Memo2.Lines.Clear; for i := 0 to Memo1.Lines.Count - 1 do begin sLine := Memo1.Lines[i]; if Length(sLine) = 0 then // 如果是空行的話 Memo2.Lines.Add(#13+#10) else repeat // 截出 _LengthPerLine 個字元出來 iCutLength := _LengthPerLine; sCuted := Copy(sLine, 1, iCutLength); iCutLength := Length(sCuted); bIsDBCS := False; // 看看最後一個字元是不是中文的前半個字 for j := 1 to iCutLength do begin if bIsDBCS then bIsDBCS := False else if Windows.IsDBCSLeadByte(byte(sCuted[j])) then bIsDBCS := True; end; // 如果最後一個字是中文的話, 少截一個字元 if bIsDBCS then Dec(iCutLength); // 截出確定長度的字元並加入 Memo2 中 Memo2.Lines.Add(Copy(sLine, 1, iCutLength)); // 從 sLine 中去掉已送至 Memo2 的文字. sLine := Copy(sLine, iCutLength + 1, Length(sLine) - iCutLength); until Length(sLine) <= 0; end; end; |
首頁 | 學習筆記 | 主題公園 | 軟體下載 | 關於本站 | 討論信群 | 相約下次 |