如何用ByteType判断截取汉字不出现乱码(45分)

  • 主题发起人 主题发起人 qingrj
  • 开始时间 开始时间
Q

qingrj

Unregistered / Unconfirmed
GUEST, unregistred user!
ByteType判断截取汉字不出现乱码, 哪怕最简单的例子就行,如在这一行截30个汉字,如何判断并截取汉字不出现乱码,
 
每取两个就合在一起,就不会乱了
 
不是,我想将字符串每30个自动换行,该如何避免截取半个汉字!
 
用一个变量记录啊
如果变量可以被2整除,那么就整个一个汉字了
否则就是半个汉字
 
我原来的字符串分条处理。TEXT代表字符串。你自己改了就可以了。有点麻烦。随便。
Function FenTiao(text:widestring):TFmess;
var
num:string;
i:byte;
begin
if length(text)>70 then
begin
Fmess.num:=length(text) div 65;
if (length(text) mod 65)>0 then
begin
Fmess.num:=Fmess.num+1
end;
num:=inttostr(Fmess.num);
if not (Fmess.num=1) then
begin
Fmess.mess1:='(1/'+num+')';
Fmess.mess2:='(2/'+num+')';
Fmess.mess3:='(3/'+num+')';
Fmess.mess4:='(4/'+num+')';
Fmess.mess5:='(5/'+num+')';
Fmess.mess6:='(6/'+num+')';
Fmess.mess7:='(7/'+num+')';
Fmess.mess8:='(8/'+num+')';
end
else
begin
Fmess.mess1:='';
end;
for i:=1 to Fmess.num do
begin
if i=1 then
Fmess.mess1:=Fmess.mess1+copy(text,1,65)
else
if i=2 then
Fmess.mess2:=Fmess.mess2+copy(text,66,65)
else
if i=3 then
Fmess.mess3:=Fmess.mess3+copy(text,131,65)
else
if i=4 then
Fmess.mess4:=Fmess.mess4+copy(text,196,65)
else
if i=5 then
Fmess.mess5:=Fmess.mess5+copy(text,261,65)
else
if i=6 then
Fmess.mess6:=Fmess.mess6+copy(text,326,65)
else
if i=7 then
Fmess.mess7:=Fmess.mess7+copy(text,391,65)
else
if i=8 then
Fmess.mess8:=Fmess.mess8+copy(text,456,65);
end;
end
else
begin
Fmess.num:=1;
Fmess.mess1:=text;
end;
result:=Fmess;
end;
 
看我的多简单!
if bytetype(aa,30) = mbTrailByte then label2.Caption:=copy(aa,1,30) else
label2.Caption:=copy(aa,1,30-1);
 
原来bytetype是个函数.......
真不知道。。。
 
我想知道一个widestring的字节数,该怎么办?比如“134啊”,我想得到5。楼上的达人知道么?
 
试一下这个函数:不会出现半个汉字
function CopyStr(SourceStr:string;CopyLen:integer):string;
var
s0,s1,s2:string;
begin
s0 := Copy(String(SourceStr),1,CopyLen-1);
s1 := Copy(String(SourceStr),1,CopyLen);
s2 := Copy(String(SourceStr),1,CopyLen+1);
if Length(WideString(s1))<>Length(WideString(s2)) then
Result := s1
else
Result := s0;
end;

 
简化一下:
function CopyStr(SourceStr:string;CopyLen:integer):string;
var
s1:string;
begin
Result := Copy(SourceStr,1,CopyLen-1);
s1 := Copy(SourceStr,1,CopyLen);
if Length(WideString(s1))<>Length(WideString(Copy(SourceStr,1,CopyLen+1))) then
Result := s1;
end;
 
直接用widestring
或者用API判斷是不是漢字。
如下
演示程序中主要是用了 IsDBCSLeadByte 这个 API 来判断某字节是否在双字节字符集(例如汉字)的前导字节集中(GB 2312-80 汉字编码中的第一个字节范围 0xA1-0xFe)



( The IsDBCSLeadByte function determines whether a character is a lead byte ?that is, the first byte

of a character in a double-byte character set (DBCS). )



procedure TForm1.Button1Click(Sender: TObject);

var

CutLengthOfLine{ 被处理字符串的总长度 }, i, j: integer;

sLine{ 被处理的源字符串 }: string;

sCuted{ 按固定长度分割出来的部分字符串 }: string;

iCutLength{ 按固定长度分割出来的部分字符串的长度 }: integer;

bIsDBCS{ 是否是汉字的前半字节 }: boolean;

begin

if edit1.text='' then begin

exit;

end;

CutLengthOfLine:=strtoint(edit1.text);

if CutLengthOfLine < 2 then begin

showmessage('CutLengthOfLine 必须大于等于 2 !');

Exit;

end;

Memo2.Lines.Clear;

for i := 0 to Memo1.Lines.Count - 1 do

begin

sLine := Memo1.Lines;

if Length(sLine) = 0 then

Memo2.Lines.Add(#13+#10)

else

repeat //开始处理字符串

iCutLength := CutLengthOfLine;

sCuted := Copy(sLine, 1, iCutLength);//从头取出 iCutLength 长的字符串

bIsDBCS := False;//先假设没有半个字符串

for j := 1 to iCutLength do //从头到尾逐个检查,至于为什么?

//原作者是这样解释的

//1. 为什麽不直接抓最後一个字元判断? 因为中文字的 Trail-byte, 其内码也可能落在 Lead-byte

// 的内码区间内.

//2. 为什麽不直接抓最後两个字元来判断? 因为前一个字的 Trail-byte 加上後一个字的 Lead-byte,

// 可能又是一个中文字.

begin

if bIsDBCS then //如果上一个字节是汉字的前半部分

bIsDBCS := False //则此时本字节是汉字的后半部分,

//所以将是否前半个汉字检测标志设为假

else

if Windows.IsDBCSLeadByte(byte(sCuted[j])) then

bIsDBCS := True;//否则检查本字节,并根据结果设置标志

end; //end of for

//如果最后一个字节的上一个字节是汉字的前半部分,则结束时

//检测标志为假,

if bIsDBCS then Dec(iCutLength);

//如果最后一个字节是汉字的前半部分, 则少截取一个字符,避免乱码

Memo2.Lines.Add(Copy(sLine, 1, iCutLength));

sLine := Copy(sLine, iCutLength + 1, Length(sLine) - iCutLength);

//拷贝出下一部分固定长度的字符串,循环处理

until Length(sLine) <= 0;

end;

memo2.setfocus;

memo2.selstart:=0;

memo2.SelLength:=0;

end;
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部