如何将utf-8转换成GB312

时间:2021-03-24 08:43:21
客户那边有业务系统,可以通过http获取返回查询的结果,但是发送和接受的xml格式都是utf-8的。现在我发送正常可以返回,结果,我使用的是idhttp控件直接收发的,方法如下:
function TForm1.GetDataFromThird(IP: string; port: Integer; ServiceName: string; ParaXML: string; var FailMsg: WideString): string;
var
  IdHTTP: TIdHTTP;
  ss, dd: TStringStream;
  url: string;
begin
  try
    IdHTTP := TIdHTTP.Create(nil);
    ss := TStringStream.Create('Params=' + ParaXML);
    dd := TStringStream.Create('');
    try
      url := 'HTTP://' + IP + ':' + inttostr(port) + '/' + ServiceName;
      log('发送地址=' + url + ',参数=' + ss.DataString);
      IdHTTP.Post(url, ss, dd);

      Result := dd.DataString;
      log('返回值=' + Result);
      if Result = '' then
      begin
        FailMsg := '成功调用接口,但是返回空值!';
      end;
    finally
      ss.Free;
      dd.Free;
      IdHTTP.Free;
    end;
  except
    on e: Exception do
    begin
      log('GetDataFromThird异常:' + e.Message);
      FailMsg := '异常:' + e.Message;
      Result := '';
    end;
  end;
end;

然后这样使用的转码:
rtGB := UTF8Decode(rt);
  rtGB := StringReplace(rtGB, 'UTF-8', 'GB2312', []);
  self.mmo2.Text := rtGB;

其中rt就是上面方法的返回值

现在的问题是:大部分返回内容,都不能正常显示中文,目前只有一个接口能正常显示中文。请问,我转码有什么问题?或者是idhttp控件需要设置些什么?

13 个解决方案

#1


Utf8ToAnsi()
调用这个函数,传入utf-8编码的字符串,返回的结果为2312的

#2


不知道是否有用?可以參考一下:

function   utf8toansistring(utf8str:string;   codepage:integer):ansistring; 
var 
  i:integer; 
  buffer:widestring; 
  ch,c1,c2:byte; 

begin 
  result:= ' '; 
  i:=1; 
  while   i <=length(utf8str)   do   begin 
      ch:=byte(utf8str[i]); 
      setlength(buffer,length(buffer)+1); 
      if   (ch   and   $80)=0   then   //1-byte 
            buffer[length(buffer)]:=widechar(ch) 
      else   begin 
      if   (ch   and   $e0)   =   $c0   then   begin   //   2-byte 
            inc(i); 
            c1   :=   byte(utf8str[i]); 
            buffer[length(buffer)]:=widechar((word(ch   and   $1f)   shl   6)   or   (c1   and   $3f)); 
        end 
        else   begin   //   3-byte 
            inc(i); 
            c1   :=   byte(utf8str[i]); 
            inc(i); 
            c2   :=   byte(utf8str[i]); 
            buffer[length(buffer)]:=widechar( 
                (word(ch   and   $0f)   shl   12)   or 
                (word(c1   and   $3f)   shl   6)   or 
                (c2   and   $3f)); 
        end; 
        end; 
      inc(i); 
    end;   //while 
    i   :=   widechartomultibyte(codepage, 
                      wc_compositecheck   or   wc_discardns   or   wc_sepchars   or   wc_defaultchar, 
                      @buffer[1],   -1,   nil,   0,   nil,   nil); 
    if   i> 1   then   begin 
        setlength(result,   i-1); 
        widechartomultibyte(codepage, 
                wc_compositecheck   or   wc_discardns   or   wc_sepchars   or   wc_defaultchar, 
                @buffer[1],   -1,   @result[1],   i-1,   nil,   nil); 
    end; 
end; 

#3


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

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

function   UnicodeToAnsi(Unicode:   string):string; 
var 
    s:string; 
    i:integer; 
    j,k:string[2]; 
begin 
    i:=1; 
    s:= ' '; 
    while   i <Length(Unicode)+1   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; 
end; 

function   ToGBK(Str:string):string; 
begin 
    result   :=     inttohex(byte(Str[1])*$100+byte(Str[2]),2); 
end; 

#4


如果實在不行,你就參考一下這裡: http://www.cnblogs.com/baoquan/articles/1027371.html

#5


<?xml version="1.0" encoding="UTF-8"?><Root ErrorMark="0" ErrorMsg="鑾峰彇涓汉淇℃伅鎴愬姛" RecCount="1"><Rec><FD Name="DWBM" Value="54901074" /><FD Name="GRDNH" Value="12345" /><FD Name="XM" Value="鏇瑰仴绁? /><FD Name="DWMC" Value="骞垮窞甯傝崝婀惧尯閫€浼戣亴宸ョ鐞嗗鍛樹細鍔炲叕瀹? /><FD Name="SFZH" Value="440107195506210019" /></Rec></Root>

这是服务器返回的utf-8的字符串,请大侠们解析下,

#6


以上都这些都解决不了问题,如果将发送的字符串直接使用ie发送,返回的结果可以正常显示的ie界面中,但是我获取到的不管转换不转换,都不能正常显示,肉眼看了下是“XM”和“DWMC”后面没有双引号。如果我将转换成GB2312的编码,然后使用XMLDocument去解析,也是没有双引号,所以会报错!!!

请大侠们看看,是不是idhttp使用的不正确?无法返回正常的utf-8编码的字符串?

#7


    try
      htmlStr := Fidhtp.Get(SearchUrl);
    except

    end;
    htmlStr := Utf8ToAnsi(htmlStr);

#8


please try agin GET的方法:

IdHTTP1.Request.AcceptCharSetvar lastbox:TStringList. begin lastbox:=TStringList.Create. try idHttp1.Request.AcceptCharSet := UTF-8. lastbox.Text:=UTF8Decode(idhttp1.Get(http://***.***.**)). // //或lastbox.Text:=Utf8ToAnsi(idhttp1.Get(http://***.***.**)). showmessage(lastbox.Text); 

#9


其實:可用WebBrowser,它取出来的好像是unicode;而IDHTTP得进行编码转换。。。
再次參考下面的DEMO:

var 
  IframeUrl: string; 
  ret:WideString;//TStringStream; 
  SourceHtmlCode: WideString; 
begin 
  IframeUrl := 'http://ctplp.blog15.fc2.com/blog-entry-33.html';//这个网站是EUC-JS编码 
  //IframeUrl := 'http://www.nhk.or.jp/furusato/koremade/koremade_ibaraki.html';//这个网站是SHIFT-JS编码 

  IdHTTP.HandleRedirects:=true; 
  IdHTTP.Request.ContentType:= 'application/x-www-form-urlencoded'; 
  IdHTTP.Request.UserAgent:= 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)'; 
  IdHTTP.Request.SetHeaders; 
  try 
    SourceHtmlCode := StringToWideString(IdHTTP.Get(IframeUrl),51932);//日文EUC編碼是51932  日文(Shift-JIS)是932 
    Memo1.Lines.Text := SourceHtmlCode; 
  except 
    ShowMessage('未找到HTTP服务器'); 
  end; 
end; 

function StringToWideString(const S: string; CodePage: Word): WideString; 
var 
    InputLength, OutputLength: Integer; 
begin 
    InputLength := Length(S); 
    OutputLength := MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, nil, 0); 
    SetLength(Result, OutputLength); 
    MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, PWideChar(Result), OutputLength); 
end; 

#10


该回复于2010-08-17 09:29:27被版主删除

#11



var
  ss : TStringStream;
begin
  ss := TStringStream.Create('', TEncoding.GetEncoding(65001)); 
  try
    IdHTTP1.Get(CSURL, ss);
    IdHTTP1.Get(CSURL);
    Memo1.Text := ss.DataString;
  finally
    ss.Free;
  end;
end;

#12


这样就可以了

var
  ss : TStringStream;
begin
  ss := TStringStream.Create('', TEncoding.GetEncoding(65001)); 
  try
    IdHTTP1.Get(URL_Address, ss);
    Memo1.Text := ss.DataString;
  finally
    ss.Free;
  end;
end;

#13


我是来学习的。

#1


Utf8ToAnsi()
调用这个函数,传入utf-8编码的字符串,返回的结果为2312的

#2


不知道是否有用?可以參考一下:

function   utf8toansistring(utf8str:string;   codepage:integer):ansistring; 
var 
  i:integer; 
  buffer:widestring; 
  ch,c1,c2:byte; 

begin 
  result:= ' '; 
  i:=1; 
  while   i <=length(utf8str)   do   begin 
      ch:=byte(utf8str[i]); 
      setlength(buffer,length(buffer)+1); 
      if   (ch   and   $80)=0   then   //1-byte 
            buffer[length(buffer)]:=widechar(ch) 
      else   begin 
      if   (ch   and   $e0)   =   $c0   then   begin   //   2-byte 
            inc(i); 
            c1   :=   byte(utf8str[i]); 
            buffer[length(buffer)]:=widechar((word(ch   and   $1f)   shl   6)   or   (c1   and   $3f)); 
        end 
        else   begin   //   3-byte 
            inc(i); 
            c1   :=   byte(utf8str[i]); 
            inc(i); 
            c2   :=   byte(utf8str[i]); 
            buffer[length(buffer)]:=widechar( 
                (word(ch   and   $0f)   shl   12)   or 
                (word(c1   and   $3f)   shl   6)   or 
                (c2   and   $3f)); 
        end; 
        end; 
      inc(i); 
    end;   //while 
    i   :=   widechartomultibyte(codepage, 
                      wc_compositecheck   or   wc_discardns   or   wc_sepchars   or   wc_defaultchar, 
                      @buffer[1],   -1,   nil,   0,   nil,   nil); 
    if   i> 1   then   begin 
        setlength(result,   i-1); 
        widechartomultibyte(codepage, 
                wc_compositecheck   or   wc_discardns   or   wc_sepchars   or   wc_defaultchar, 
                @buffer[1],   -1,   @result[1],   i-1,   nil,   nil); 
    end; 
end; 

#3


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

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

function   UnicodeToAnsi(Unicode:   string):string; 
var 
    s:string; 
    i:integer; 
    j,k:string[2]; 
begin 
    i:=1; 
    s:= ' '; 
    while   i <Length(Unicode)+1   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; 
end; 

function   ToGBK(Str:string):string; 
begin 
    result   :=     inttohex(byte(Str[1])*$100+byte(Str[2]),2); 
end; 

#4


如果實在不行,你就參考一下這裡: http://www.cnblogs.com/baoquan/articles/1027371.html

#5


<?xml version="1.0" encoding="UTF-8"?><Root ErrorMark="0" ErrorMsg="鑾峰彇涓汉淇℃伅鎴愬姛" RecCount="1"><Rec><FD Name="DWBM" Value="54901074" /><FD Name="GRDNH" Value="12345" /><FD Name="XM" Value="鏇瑰仴绁? /><FD Name="DWMC" Value="骞垮窞甯傝崝婀惧尯閫€浼戣亴宸ョ鐞嗗鍛樹細鍔炲叕瀹? /><FD Name="SFZH" Value="440107195506210019" /></Rec></Root>

这是服务器返回的utf-8的字符串,请大侠们解析下,

#6


以上都这些都解决不了问题,如果将发送的字符串直接使用ie发送,返回的结果可以正常显示的ie界面中,但是我获取到的不管转换不转换,都不能正常显示,肉眼看了下是“XM”和“DWMC”后面没有双引号。如果我将转换成GB2312的编码,然后使用XMLDocument去解析,也是没有双引号,所以会报错!!!

请大侠们看看,是不是idhttp使用的不正确?无法返回正常的utf-8编码的字符串?

#7


    try
      htmlStr := Fidhtp.Get(SearchUrl);
    except

    end;
    htmlStr := Utf8ToAnsi(htmlStr);

#8


please try agin GET的方法:

IdHTTP1.Request.AcceptCharSetvar lastbox:TStringList. begin lastbox:=TStringList.Create. try idHttp1.Request.AcceptCharSet := UTF-8. lastbox.Text:=UTF8Decode(idhttp1.Get(http://***.***.**)). // //或lastbox.Text:=Utf8ToAnsi(idhttp1.Get(http://***.***.**)). showmessage(lastbox.Text); 

#9


其實:可用WebBrowser,它取出来的好像是unicode;而IDHTTP得进行编码转换。。。
再次參考下面的DEMO:

var 
  IframeUrl: string; 
  ret:WideString;//TStringStream; 
  SourceHtmlCode: WideString; 
begin 
  IframeUrl := 'http://ctplp.blog15.fc2.com/blog-entry-33.html';//这个网站是EUC-JS编码 
  //IframeUrl := 'http://www.nhk.or.jp/furusato/koremade/koremade_ibaraki.html';//这个网站是SHIFT-JS编码 

  IdHTTP.HandleRedirects:=true; 
  IdHTTP.Request.ContentType:= 'application/x-www-form-urlencoded'; 
  IdHTTP.Request.UserAgent:= 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)'; 
  IdHTTP.Request.SetHeaders; 
  try 
    SourceHtmlCode := StringToWideString(IdHTTP.Get(IframeUrl),51932);//日文EUC編碼是51932  日文(Shift-JIS)是932 
    Memo1.Lines.Text := SourceHtmlCode; 
  except 
    ShowMessage('未找到HTTP服务器'); 
  end; 
end; 

function StringToWideString(const S: string; CodePage: Word): WideString; 
var 
    InputLength, OutputLength: Integer; 
begin 
    InputLength := Length(S); 
    OutputLength := MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, nil, 0); 
    SetLength(Result, OutputLength); 
    MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, PWideChar(Result), OutputLength); 
end; 

#10


该回复于2010-08-17 09:29:27被版主删除

#11



var
  ss : TStringStream;
begin
  ss := TStringStream.Create('', TEncoding.GetEncoding(65001)); 
  try
    IdHTTP1.Get(CSURL, ss);
    IdHTTP1.Get(CSURL);
    Memo1.Text := ss.DataString;
  finally
    ss.Free;
  end;
end;

#12


这样就可以了

var
  ss : TStringStream;
begin
  ss := TStringStream.Create('', TEncoding.GetEncoding(65001)); 
  try
    IdHTTP1.Get(URL_Address, ss);
    Memo1.Text := ss.DataString;
  finally
    ss.Free;
  end;
end;

#13


我是来学习的。