首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将AnsiChar转换为WideChar?

如何将AnsiChar转换为WideChar?
EN

Stack Overflow用户
提问于 2013-06-30 06:57:31
回答 2查看 3.9K关注 0票数 0

例如,我有一个AnsiChar "A“,我想把它转换成一个宽字符串(不需要进行类型转换!)。我在考虑一些内存操作,但我不知道在WideChar中(在内存中) AnsiChar会是什么样子。也许还有一个WinAPI命令?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-30 07:00:36

类型转换有什么问题?

如果你这样做了,它是有效的,但我会在这篇文章的后面告诉你为什么它是错误的。:p

代码语言:javascript
复制
var
  A: AnsiChar;
  B: WideChar;
begin
  A := 'a';
  B := WideChar(A);

关于ANSI和ASCII (和UCS-2)

AnsiChars是单字节字符。WideChars是使用UCS-2编码的双字节字符,它是UTF-16的子集。

这意味着对于前127个ANSI字符(这是ASCII字符集,包含大多数通俗易懂的字符)几乎相同,只是它是2个字节而不是1个字节。因此,在ASCII码中具有$40 (十六进制)字节值的大写'A‘变成字节$00 + $40作为WideChar。它们只是零填充的。

对于ANSI集合的上半部分,这并不容易,因为这些字符可能具有不同的含义,具体取决于所使用的代码页。此范围可以包含希腊字符、西欧字符(如é)或其他字符,但不能包含所有字符的组合,因为在该范围内只能容纳128个字符。因此,要将ANSI转换为WideChar,您必须知道(或假定)代码页。所有(或大部分)代码页在widechar支持的65536个不同字符的总范围内具有不同的位置。

关于类型转换的

也就是说,我可以在上面的代码片段中添加一个é,它仍然可以意外地工作。Delphi实际上只是将字节值转换为双字节值,因此将AnsiChar类型转换为WideChar基本上与将Byte值赋给Word相同。没有完成真正的转换。碰巧的是,不仅UTF-16的第一个“基本拉丁语”平面与ASCII匹配,而且第二个“Latin1补充平面”也与西欧人的ANSI表中的ISO8859-1字符集匹配。因此,我只需在现有字符之间添加值为0的字节,就可以将所有文本迁移到WideCharacters。

但并不是所有的人都这么幸运。如果你有一个俄语文本在Ansi中,那么这个类型转换将不起作用。要正确地做到这一点,请确保您有Delphi 2009或更高版本,它支持unicode字符串,并具有各种工具来在编码之间和各种ANSI代码页之间进行转换。

B.t.w.,对于AnsiChar到WideChar,你需要一个类型转换,这毕竟是一个普通的整数赋值,但你实际上可以将一个AnsiString赋给一个WideString,Delphi会为你隐藏所有的转换,并实际上将其编译为对_WStrFromLStr的调用,这是在System单元中定义的,以防你想要研究它是如何工作的。

我希望这能回答您的具体问题,但是您可能想要阅读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)。总的来说,这是对unicode的一个很好的解释。在其中,您可以找到我提到的Ansi、ASCII和UCS-2,但它们都放在更多的上下文中。

票数 13
EN

Stack Overflow用户

发布于 2013-06-30 15:53:53

提供了Windows API函数MultiByteToWideChar来执行此转换。当然,您需要指定输入数据的代码页。例如:

代码语言:javascript
复制
function AnsiCharToWideChar(ac: AnsiChar; CodePage: UINT): WideChar;
begin
  if MultiByteToWideChar(CodePage, 0, @ac, 1, @Result, 1) <> 1 then
    RaiseLastOSError;
end;

请注意,ANSI代码页中定义的所有字符都映射到基本多语言平面中的Unicode字符,因此由单个UTF-16字符表示。因此,上面代码的大小假设。

但是,您所做的假设是,单个字节表示ANSI字符集中的一个字符。对于许多字符集来说,这是一个有效的假设,例如像1252这样的单字节西部字符集。但是像932 (日语)、949 (朝鲜语)等字符集是双字节字符集。对于这些代码页,您的整个方法和上面的代码都被分解了。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17385456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档