Lazarus 1.8 Unicode 字符与UTF8字符的转换
我有一个文本文件,在WINDOWS 7 X64简体中文版中存储格式是UCS2,我想用LAZARUS 1.8 写一工具进行格式化,发现用MEMO1导入后显示乱码,经查,是LAZARUS 1.8 默认用UTF8处理字符,包括MEMO控件,所以需要转码,但测试了LAZutf8单元的工具都没有可用的,于是写下如下转码函数:
// UCS2格式文本转换为UTF8
// UCS2格式以两个字节UNICODE编码字符,所以只有保存码值为0XFFFF 之前的字符
// UCS2格式保存时,是低字先存,高字后存,如严字UNICODE编码为4E25,保存时先存25,再存4E
// C1,C2为UCS2文件中连续的两个字节
function UCS2ToUTF8(C1,C2:byte):UTF8string;
var
SH,SM,SL:Byte;
VL,VH:Byte;
V:Word;
begin
result:='';
VL:=C1; //25
VH:=C2; //4E
V:=VH;
V:=(V SHL 8)+VL;
if (V>=$0000) AND (V<=$007F) then
begin
result:=Chr(VL);
end
else if (v>=$0080) and (v<=$07ff) then
begin
SM:=VL SHR 6;
VL:=%10000000 +(%00111111 AND VL);
VH:=%11000000 +(VH SHL 2)+SM;
Result:=chr(VH)+CHR(VL);
end
else if (v>=$0800) and (v<=$FFFF) then
begin
SL:=%10000000+(%00111111 AND VL);
SM:=%10000000+(VL SHR 6);
SM:=SM+((VH SHL 2) AND %00111100);
SH:=%11100000+(VH SHR 4);
Result:=chr(SH)+CHR(SM)+CHR(SL);
end;
end;
下面是检测文本文件格式的函数:
//检测文本文件编码格式
function TextEncode(FileName:String):string;
var
fs:TFileStream;
flag:array[0..1] of byte;
begin
flag[0]:=0;
flag[1]:=0;
fs:=TFileStream.Create(FileName,fmOpenRead);
ALenth:=fs.Size;
fs.read(flag,2);
fs.Free;
if (flag[0]=$EF) AND (flag[1]=$BB) then
Result:='UTF-8'
else if (flag[0]=$FE) AND (flag[1]=$FF) then
Result:='BigEndianUnicode'
else if (flag[0]=$FF) AND (flag[1]=$FE) then
Result:='Unicode'
else
Result:='ANSI';
end;
转码原理参考文档:字符编码笔记 阮一峰的博客文章