如何将UTF8字符品转成GB2312或BIG5?(200分)

  • 主题发起人 主题发起人 gztiger
  • 开始时间 开始时间
G

gztiger

Unregistered / Unconfirmed
GUEST, unregistred user!
已知如如下串
%E7%B9%BD%E7%B4%9B%E8%8A%B1%E5%BA%97
是繁体 繽紛花店 的UTF8编码。

请问如何在Delphi中将如上代码转成BIG5显示出来?
 
Utf8ToAnsi行不?
 
谢谢xf-wangyi,好像不行~~
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=21698
看我的笔记。。。
 
%E7%B9%BD%E7%B4%9B%E8%8A%B1%E5%BA%97不是UTF-8
应该是UNICODE。。
//UniCode->GB CHT
WideCharToMultiByte(936,0,pUniCodeChar,-1,pGBCHTChar,Len,nil,nil);
 
to 蓝叶菱:
你的笔记打不开,提示是”对不起,此笔记是私人笔记,其他人不能查看。”可以公开看看吗?谢谢!
 
作者?: 蓝叶菱
标题?: utf8-GB-BIG5转换
关键字: utf8-GB-BIG5
分类?: 个人专区
密级?: 私有
(评分: , 回复: 0, 阅读: 2) »»
我根据VC++改的
在两个操作环境下都测试能过

//*****************************************************
//Function BIG5ToGB
//Para :BIG5 String
//Return : GB AnsiString
//BIG5 -> UniCode ->GB CHT -> GB CHS
//Function GBToBIG5
//Para : GB String
//Return : BIG5 AnsiString
//GB CHS -> GB CHT -> UniCode -> Big5
//******************************************************

unit UGBBig5Convert;

interface

uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs;

type
TGBBIG5Convert = class(TObject)
public
class function BIG5ToGB(BIG5Str : String): AnsiString;
class function GBToBIG5(GBStr : String): AnsiString;
end;


implementation

{
******************************** TGBBIG5Convert ********************************
}
class function TGBBIG5Convert.BIG5ToGB(BIG5Str : String): AnsiString;
var
Len: Integer;
pBIG5Char: PChar;
pGBCHSChar: PChar;
pGBCHTChar: PChar;
pUniCodeChar: PWideChar;
begin
//String -> PChar
pBIG5Char := PChar(BIG5Str);

Len := MultiByteToWideChar(950,0,pBIG5Char,-1,nil,0);

GetMem(pUniCodeChar,Len);
ZeroMemory(pUniCodeChar,Len);
//Big5 -> UniCode
MultiByteToWideChar(950,0,pBIG5Char,-1,pUniCodeChar,Len);

Len := WideCharToMultiByte(936,0,pUniCodeChar,-1,nil,0,nil,nil);

Try
GetMem(pGBCHTChar,Len*2);
ZeroMemory(pGBCHTChar,Len*2);

GetMem(pGBCHSChar,Len*2);
ZeroMemory(pGBCHSChar,Len*2);
//UniCode->GB CHT
WideCharToMultiByte(936,0,pUniCodeChar,-1,pGBCHTChar,Len,nil,nil);
//GB CHT -> GB CHS
LCMapString($804,LCMAP_SIMPLIFIED_CHINESE,pGBCHTChar,-1,pGBCHSChar,Len);

Result := String(pGBCHSChar);
Finally
FreeMem(pGBCHTChar);
FreeMem(pGBCHSChar);
end;
end;

class function TGBBIG5Convert.GBToBIG5(GBStr : String): AnsiString;
var
Len: Integer;
pGBCHTChar: PChar;
pGBCHSChar: PChar;
pUniCodeChar: PWideChar;
pBIG5Char: PChar;
begin
pGBCHSChar := PChar(GBStr);
Len := MultiByteToWideChar(936,0,pGBCHSChar,-1,nil,0);

Try
GetMem(pGBCHTChar,Len*2+1);
ZeroMemory(pGBCHTChar,Len*2+1);
//GB CHS -> GB CHT
LCMapString($804,LCMAP_TRADITIONAL_CHINESE,pGBCHSChar,-1,pGBCHTChar,Len*2);


GetMem(pUniCodeChar,Len*2);
ZeroMemory(pUniCodeChar,Len*2);
//GB CHT -> UniCode
MultiByteToWideChar(936,0,pGBCHTChar,-1,pUniCodeChar,Len*2);

Len := WideCharToMultiByte(950,0,pUniCodeChar,-1,nil,0,nil,nil);
Try
GetMem(pBIG5Char,Len);
ZeroMemory(pBIG5Char,Len);
//UniCode -> Big5
WideCharToMultiByte(950,0,pUniCodeChar,-1,pBIG5Char,Len,nil,nil);

Result := String(pBIG5Char);
Finally
FreeMem(pBIG5Char);
end;
Finally
FreeMem(pGBCHTChar);
end;
end;


end.
 
UNICODE-BIG-BIG5的看我的笔记吧。
http://www.delphibbs.com/keylife/iblog_show.asp?xid=22693
delphi 编码转换 unicode gbk big5
(转载)
[ 2006-03-23 15:39:23 | 作者: Admin ]
字体大小: 大 | 中 | 小
以下代码在DELPHI 7上调试通过,主要使用了api函数中MultiByteToWidechar

function UnicodeEncode(Str:string;CodePage:integer):WideString;
var
Len:integer;
begin
Len:=Length(Str)+1;
SetLength(Result,Len);
Len:=MultiByteToWideChar(CodePage,0,PChar(Str),-1,PWideChar(Result),Len);
SetLength(Result,Len-1); //end is #0
end;

function UnicodeDecode(Str:WideString;CodePage:integer):string;
var
Len:integer;
begin
Len:=Length(Str)*2+1; //one for #0
SetLength(Result,Len);
Len:=WideCharToMultiByte(CodePage,0,PWideChar(Str),-1,PChar(Result),Len,nil,nil);
SetLength(Result,Len-1);
end;

function Gb2Big5(Str:string):string;
begin
SetLength(Result,Length(Str));
LCMapString(GetUserDefaultLCID,LCMAP_TRADITIONAL_CHINESE,
PChar(Str),Length(Str),
PChar(Result),Length(Result));
Result:=UnicodeDecode(UnicodeEncode(Result,936),950);
end;

function Big52Gb(Str:string):string;
begin
Str:=UnicodeDecode(UnicodeEncode(Str,950),936);
SetLength(Result,Length(Str));
LCMapString(GetUserDefaultLCID,LCMAP_SIMPLIFIED_CHINESE,
PChar(Str),Length(Str),
PChar(Result),Length(Result));
end;

关键使用了UnicodeToUtf8这个函数
function Utf8Encode(const WS: WideString): UTF8String;
var
L: Integer;
Temp: UTF8String;
begin
Result := '';
if WS = '' then Exit;
SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator
L := UnicodeToUtf8(PChar(Temp), Length(Temp)+1, PWideChar(WS), Length(WS));
if L > 0 then
SetLength(Temp, L-1)
else
Temp := '';
Result := Temp;
end; -
=======================
方法二:
 
To: 蓝叶菱:
谢谢你,你的回复很详尽了,但说真的这个东西真的把我搞晕了...我现在还找不到北。至于编码该是UTF8(确切地说是Unicode的一种)的。我这有一段代码:
<%
item_no=replace(trim(request("item_no")),"'","")
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>UTF8内码转换器</title>
<%

function UTF2GB(UTFStr)
for Dig=1 to len(UTFStr)
if mid(UTFStr,Dig,1)="%" then
if len(UTFStr) >= Dig+8 then
GBStr=GBStr & ConvChinese(mid(UTFStr,Dig,9))
Dig=Dig+8
else
GBStr=GBStr & mid(UTFStr,Dig,1)
end if
else
GBStr=GBStr & mid(UTFStr,Dig,1)
end if
next
UTF2GB=GBStr
end function

function ConvChinese(x)
A=split(mid(x,2),"%")
i=0
j=0

for i=0 to ubound(A)
A(i)=c16to2(A(i))
next

for i=0 to ubound(A)-1
DigS=instr(A(i),"0")
Unicode=""
for j=1 to DigS-1
if j=1 then
A(i)=right(A(i),len(A(i))-DigS)
Unicode=Unicode & A(i)
else
i=i+1
A(i)=right(A(i),len(A(i))-2)
Unicode=Unicode & A(i)
end if
next

if len(c2to16(Unicode))=4 then
ConvChinese=ConvChinese & chrw(int("&H" & c2to16(Unicode)))
else
ConvChinese=ConvChinese & chr(int("&H" & c2to16(Unicode)))
end if
next
end function

function c2to16(x)
i=1
for i=1 to len(x) step 4
c2to16=c2to16 & hex(c2to10(mid(x,i,4)))
next
end function

function c2to10(x)
c2to10=0
if x="0" then exit function
i=0
for i= 0 to len(x) -1
if mid(x,len(x)-i,1)="1" then c2to10=c2to10+2^(i)
next
end function

function c16to2(x)
i=0
for i=1 to len(trim(x))
tempstr= c10to2(cint(int("&h" & mid(x,i,1))))
do while len(tempstr)<4
tempstr="0" & tempstr
loop
c16to2=c16to2 & tempstr
next
end function

function c10to2(x)
mysign=sgn(x)
x=abs(x)
DigS=1
do
if x<2^DigS then
exit do
else
DigS=DigS+1
end if
loop
tempnum=x

i=0
for i=DigS to 1 step-1
if tempnum>=2^(i-1) then
tempnum=tempnum-2^(i-1)
c10to2=c10to2 & "1"
else
c10to2=c10to2 & "0"
end if
next
if mysign=-1 then c10to2="-" & c10to2
end function
%>
</head>
<body>
<% Response.write(item_no)%>==>:
<% Response.write UTF2GB(item_no)%>
<form name="form1" method="post" action="aa.asp?ss=<%=item_no%>">
<font color="#08719C">utf-8:</font>
</td>
<textarea name="item_no" cols="100"></textarea>
<input type="submit" name="Submit" value="提交" >
<input type="reset" name="Submit2" value="重置" >
</form>
</body>
</html>
是一个ASP文件,我可将上面的字符串转成繁体的汉字。但在Delhpi我现不知如何下手。
老兄能否提供一个样例?或者用你的方式试一下我那字符串?不胜感激!
 
DELPHI例子,代码函数已经提供了,
不过如果是ASP程序的话,你可以自己开发Active Server Libary就OK了,可以利用上面的函数,不过,DELPHI建立ASP的DLL的同时,你可以直接使用IServer.HtmlEncode根本不需要转换,不过对于BIG的转换还得参考以上的函数。
<form name="form1" method="post" action="aa.asp?ss=<%=item_no%>">需要转化吗?
我晕,不知道你究竟想问什么。。。
函数也有了,你的ASP函数也有了,DELPHI函数也有了,ASP直接使用
DELPHI可以开发Active Server Libary,或者Internet Express,
我倒,我倒,我晕,我晕,问的让人糊涂。
 
我前不久写了一个工具,包含Unicode、UTF8、URL到STRING的互相转换,先把代码SHOW一下吧。
////////////////////////////////////////////////////////////////////////////
//Unit1.pas
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,URL;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Edit3: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
//function UnicodeToAnsi(Unicode: string): string;
private
{ Private declarations }
public
{ Public declarations }
utf:string;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function ReadHex(AString: string): integer;
begin
try
Result:=StrToInt('$'+AString);
except
Result:=0;
end;
end;

function AnsiToUnicode(Ansi: string): string;
var
s:string;
i:integer;
j,k:string[2];
a:array [1..1000] of char;
begin
try
s:='';
StringToWideChar(Ansi,@(a[1]),500);
i:=1;
while ((a<>#0) or (a[i+1]<>#0)) do begin
j:=IntToHex(Integer(a),2);
k:=IntToHex(Integer(a[i+1]),2);
s:=s+k+j;
i:=i+2;
end;
Result:=s;
except
Result:='';
end;
end;

function UnicodeToAnsi(Unicode: string): string;
var
s:string;
i:integer;
j,k:string[2];
begin
i:=1;
s:='';
try
while i<length(unicode) do
begin
j:=Copy(Unicode,i+2,2);
k:=Copy(Unicode,i,2);
i:=i+4;
s:=s+Char(ReadHex(j))+Char(ReadHex(k));
end;
if s<>'' then
s:=WideCharToString(PWideChar(s+#0#0#0#0))
else
s:='';
Result:=s;
except
Result:='';
end;
end;

function StrToUTF8(str: WideString): string;
var
s: pchar;
i: integer;
tmp: string;
begin
tmp := '';
result := '';
s := pchar(Utf8encode(str));
for i := 0 to strlen(s)-1 do begin
tmp := tmp + format('%2.2x', [ord(s)]);
end;
result := tmp;
end;

function UTF8ToStr(const str: UTF8String): string;
var
s: pchar;
i: integer;
tmp: string;
begin
tmp := '';
result := '';
s := PChar(str);
i := 0;
while i < length(s) do begin
tmp := tmp + chr(HexToInt(s + s[i + 1]));
inc(i, 2);
end;
result := Utf8Decode(tmp);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
self.Edit2.Text:=AnsiToUnicode(self.Edit1.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Edit3.Text:=UTF8ToStr(Edit2.Text);
//Edit3.Text:=UTF8toAnsi(Edit2.Text);
end;


procedure TForm1.Button3Click(Sender: TObject);
begin
Edit2.Text:=StrToUTF8(Edit1.Text);
//Edit2.Text:=AnsiToUTF8(self.Edit1.Text);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
Edit3.Text:=UnicodeToAnsi(Edit2.Text);
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
Edit2.Text:=UrlEncode(Edit1.Text,false);
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
Edit3.Text:=UrlDecode(Edit2.Text);
end;

end.

///////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////////////////
//URL.pas

unit URL;

interface

uses SysUtils;

function UrlEncode(const DecodedStr: String; Pluses: Boolean): String;

function UrlDecode(const EncodedStr: String): String;

function HexToInt(HexStr: String): Int64;

implementation

function UrlEncode(const DecodedStr: String; Pluses: Boolean): String;
var
I: Integer;
begin
Result := '';
if Length(DecodedStr) > 0 then
for I := 1 to Length(DecodedStr) do
begin
if not (DecodedStr in ['0'..'9', 'a'..'z',
'A'..'Z', ' ']) then
Result := Result + '%' + IntToHex(Ord(DecodedStr), 2)
else if not (DecodedStr = ' ') then
Result := Result + DecodedStr
else
begin
if not Pluses then
Result := Result + '%20'
else
Result := Result + '+';
end;
end;
end;

function UrlDecode(const EncodedStr: String): String;
var
I: Integer;
begin
Result := '';
if Length(EncodedStr) > 0 then
begin
I := 1;
while I <= Length(EncodedStr) do
begin
if EncodedStr = '%' then
begin
Result := Result + Chr(HexToInt(EncodedStr[I+1]
+ EncodedStr[I+2]));
I := Succ(Succ(I));
end
else if EncodedStr = '+' then
Result := Result + ' '
else
Result := Result + EncodedStr;

I := Succ(I);
end;
end;
end;

function HexToInt(HexStr: String): Int64;
var RetVar : Int64;
i : byte;
begin
HexStr := UpperCase(HexStr);
if HexStr[length(HexStr)] = 'H' then
Delete(HexStr,length(HexStr),1);
RetVar := 0;

for i := 1 to length(HexStr) do begin
RetVar := RetVar shl 4;
if HexStr in ['0'..'9'] then
RetVar := RetVar + (byte(HexStr) - 48)
else
if HexStr in ['A'..'F'] then
RetVar := RetVar + (byte(HexStr) - 55)
else begin
Retvar := 0;
break;
end;
end;

Result := RetVar;
end;

end.

///////////////////////////////////////////////////////////////////////
 
这回你应该看得懂了吧。新建一个Project,直接把代码复制进去,编译就出来了。


看着给分吧。
 
[red]请注意:我的代码中已经把“%”过滤了。但是功能完全符合你的要求。不管是GB2312还是BIG5,都可以正常转换。[/red]
 
谢谢goostudio 和 蓝叶菱 这两 天脑子是有点晕...
不过goostudio的真的把我的问题解决了。
顺便说说问题起因吧:
这两天港版P910数据同步失败,好像是主板有点问题,于是将电话里的所有通讯录通过蓝牙传到了电脑上,是一个.vcf文件。在繁体简体的windows中都试了,用通讯簿导入.vcf文件后繁体中文字都是乱码。用记事本打开.vcf文件后发现里面是如下格式:
BEGIN:VCARD
VERSION:2.1
REV:20041201T013823Z
N;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:=E7=B9=BD=E7=B4=9B=E8=8A=B1=E5=BA=97;;;;
FN;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:=E7=B9=BD=E7=B4=9B=E8=8A=B1=E5=BA=97
END:VCARD
将UTF-8后面的将=号改成%后我试着在原来收藏asp中试过,可以正常转换,于是想在Delphi中将这个文件批量转换好。于是有了这个问题。

谢谢两位!
 
楼主说得没有错,<E7 B9 BD E7 B4 9B E8 8A B1 E5 BA 97>的确是“繽紛花店”的UTF-8编码。Unicode本身并不是一种编码,而是编码字符集,具体的编码应该指的是UTF-8、UTF-16和UTF-32这些,所以UTF-8才是Unicode的一种编码方式。

把UTF-8字符串转换成BIG5字符串的方法很简单,只要依次调用Utf8ToUnicode(这个函数的功能是把UTF-8字符串转换成宽字符串也就是WideString),然后再用WideCharToMultiByte函数把宽字符串转换成BIG5就可以了(转BIG5的时候要把代码页参数设为950)。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部