delphi - 如何在delphi 2010中将中文字符串转换为十六进制并达到与delphi 2007 mbcs相同的结果

标签 delphi

此代码在delphi2007中转换成功 例如: 我有一个中文短刀,在delphi2007中转换为B5 CC B5 C6,但在delphi 2010中转换为77 ED 52 00

    function StringToHex(str: string): string;
    var

       i:integer;
       s:string;
    begin
       s:='';

       for i:=1 to length(str) do begin
           s:=s+inttohex(Integer(str[i]),2);
       end;
       result:=s;
    end;

但是在delphi2010中,这是错误的 谁能编辑它在delphi2010中工作成功吗?

最佳答案

首先,在 Delphi 2007 中,String=AnsiString,在 Delphi 2010 中,String=UnicodeString。如果您知道 AnsiString(char 是 8 位)和 UnicodeString(char 是 16 位)的含义,那么这足以让您理解。

即使您正在调用“IntToHex(x,2)”,每个 Delphi 2010 字符在转换为整数时都将在 0 到 65535 的范围内,这意味着 IntToHex 调用返回 2 到 4 个十六进制数字,这使得您很难不混淆地读取结果。

一个最小的unicode感知修复是将delphi的unicode版本更改为IntToHex(x,4),并且可能在其中放置一个空格,这样您至少可以看到代码点分隔四位数字的位置,例如0000 对于表示为十六进制的单个 unicode 字符来说足够的十六进制数字。两位数不够。

为什么值不同?这是个好问题。让我试着说得更清楚;我相信您正在看到使用 Delphi 2007 及其 ANSI+MBCS 支持(依赖于代码页)与使用 Unicode 字符串的 Delphi 2010 的结果。 MBCS 值与 unicode 代码点不同,您不应感到惊讶。

您还应该知道,需要两个十六进制数字来显示一个字节,需要四个十六进制数字来显示一个 Unicode 字符,其大小为 16 位。

如果您确实想查看 UTF8 字符串的十六进制,那么在 Delphi 2010 中您必须首先创建一个 UTF8 字符串。如果您确实想要 MBCS,请直说。现在全世界都是Unicode了,我建议你放弃MBCS。

Unicode 字符串字符代码点的固定代码(4 个十六进制数字,16 位):

UnicodeString=字符串感知版本(Delphi 2009,2010,XE):

function StringToHex16(str: string): string;
var
   i:integer;
   s:string;
begin
       s:='';

       for i:=1 to length(str) do begin
           s:=s+inttohex(Integer(str[i]),4);
       end;
       result:=s;

end;

Delphi 2009、2010、XE 的 UTF8 版本:

function StringToHexUtf8(str: string): string;
var
   i:integer;
   s:string;
   u:RawByteString;
begin
       u := Utf8String(str);
       s:='';

       for i:=1 to length(u) do begin
           s:=s+inttohex(Integer(u[i]),2);
       end;
       result:=s;

end;

最后,由于您可能想要准确地重现 Delphi 2007 的行为,因此这里是一个使用 MBCS 函数的明确示例:

function StringToHexMbcs(str: string;cp:Integer): string;
var
   sz,i:integer;
   s:string;
   u:RawByteString;
   flags:Integer;
begin
  // use cp 936 or 950 for simplified or traditional chinese mbcs.
  flags := WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR;
  sz := Windows.WideCharToMultiByte(  cp,  flags, @str[1],-1,nil,0,nil,nil); // get length.
  SetLength(u,sz+1);
  Windows.WideCharToMultiByte(  cp,  flags, @str[1],Length(str),@u[1],sz-1, nil,nil);
  s:='';
  for i:=1 to sz do begin
        s:=s+inttohex(Integer(u[i]),2);
  end;
  result:=s;
end;

但为了将来的引用,Delphi 2007 并不是什么是“正确”的黄金标准。您必须付出一些努力来理解 MBCS 和 Unicode 之间的区别。

关于delphi - 如何在delphi 2010中将中文字符串转换为十六进制并达到与delphi 2007 mbcs相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6798723/

相关文章:

delphi - Delphi 通用 TInterfaceList 可能吗?

delphi - 寻找文本文件

delphi - 什么是 ActiveX 容器?

delphi - 生成 FASTMM 报告而不显示关闭对话框

delphi - FindFirst 以英语返回文件夹 - Delphi

delphi - 在 dbedit 按键上过滤 DBGrid 上的数据

delphi - 在组件事件中插入指令

delphi - 如何将运行时创建的按钮添加到数组中?

delphi - 如何在编辑控件中偏移光标的位置?

delphi - 如何声明一个指针(byte^)?