Winapi 如何在编码之间获得最佳匹配的unicode字符映射

Winapi 如何在编码之间获得最佳匹配的unicode字符映射,winapi,unicode,internationalization,character-encoding,globalization,Winapi,Unicode,Internationalization,Character Encoding,Globalization,我有一个UTF-16字符串,其中包含一些无法在本地Windows-1252代码页中直接表示的字符: 6/23/2011 9:23:44 ᴀᴍ 我用于将字符串转换为本地代码页(北美计算机上的Windows-1252): 字符串显示为: 6/23/2011 9:23:44 ?? 对于不可表示的字符,字面上带有问号0x3f=“?” 当您查看原始字符串中的字符时“ᴀᴍ", 这两个字符是: ᴀU+1D00:拉丁文字母小写字母A ᴍU+1D0D:拉丁文字母小写字母M unicode标准规定。对我来说

我有一个UTF-16字符串,其中包含一些无法在本地
Windows-1252
代码页中直接表示的字符:

6/23/2011 9:23:44 ᴀᴍ
我用于将字符串转换为本地代码页(北美计算机上的Windows-1252):

字符串显示为:

6/23/2011 9:23:44 ??
对于不可表示的字符,字面上带有问号
0x3f=“?”

当您查看原始字符串中的字符时“ᴀᴍ", 这两个字符是:

  • U+1D00:拉丁文字母小写字母A
  • U+1D0D:拉丁文字母小写字母M
unicode标准规定。对我来说,这意味着文本应转换为:

6/23/2011 9:23:44 AM


另一个例子是
6′2〃

  • '
    U+2032:素数
  • U+2033:双素数
当我将该字符串转换为
Windows-1252
时,它变成
6'2?
(撇号,

将撇号列为备选符号:

2032   ′   PRIME
           = minutes, feet
           → 0027 ' apostrophe
           → 00B4 ´ acute accent
           → 02B9 ʹ modifier letter prime
尽管目标代码页中不存在prime,但
WideChartoMultiByte
正在将其转换为最接近的等价物之一(即撇号)

另一方面,双素数

2033   ″   DOUBLE PRIME
           = seconds, inches
           → 0022 " quotation mark
           → 02BA ʺ modifier letter double prime
           → 201D ” right double quotation mark
           ≈ 2032 ′ 2032 ′
正在映射为nothing(
),但我的Windows-1252编码中存在一些其他项:

Character                                 Unicode  Windows-1252
========================================= =======  ============
″ double prime                            U+2032      -
" quotation mark                          U+0022     0x22
ʺ modifier letter double prime            U+02BA      -
” right double quotation mark             U+201D     0x94

′ prime                                   U+2032      -
' apostrophe                              U+0027     0x27
´ acute accent                            U+00B4     0xb4
ʹ modifier letter prime                   U+02B9
即使在最坏的情况下,它将原始的
双素数
分解为
素数
素数
:素数有一个等价物,因为它已经使用了它

对于其他字符,还存在映射:

Character                                 Unicode  Windows-1252
========================================= =======  ============
ᴀ Latin Letter Small Capital A            U+1D00      -
A Latin Capital Letter A                  U+0041     0x41
a Latin Small Letter A                    U+0061     0x61

ᴍ Latin Letter Small Capital M            U+1D0D      -
M Latin Capital Letter M                  U+004D     0x4d
m Latin Small Letter M                    U+006D     0x6d

如何使
WideChartoMultiByte
在编码之间进行最佳匹配映射?

我认为您无法更改
WideChartoMultiByte()
的结果。如果您非常在意尝试不同的解决方案,可能会得到不同的结果


就我个人而言,我还没有尝试过,所以我不能保证结果(不管怎样,谁需要从Unicode转换过来?),但我相信你应该练习一下。它的好处是,它支持Unicode 6.0(不管怎样,你可能不需要).

WideChartMultiByte的性能如何可能取决于您使用的Windows版本。我相信较新版本使用的是更完整的表。然而,它可能永远不会涵盖所有情况。由于Windows本机更喜欢Unicode,因此他们没有太多的动力来实现大量代码的所有回退情况页面在那里


您可以选择使用库(如其他人提到的ICU)或构建自己的预处理器来处理回退。

如果您知道您的目标编码,您可以使用Posix标准化的iconv
库(也可用于Windows),并从WCHAR_T或UTF-16转换为您的目标编码;iconv有一个“音译“选项,可以将您的所有特殊需要字符转换为ASCII音译。Iconv的重量比ICU轻一点,可供广泛使用。

因不能使用而被接受。我真的不想为了让一个函数正常工作而在我的软件中附带一个dll。@Ian Boyd:你可以做到;只是窗户不能为你做所有的事。您可以编写一个预处理器,在将其传递给WideChartMultiByte之前执行回退替换。它需要一个从Unicode字符数据库构建的稀疏表,这是一个简单的下载。
Character                                 Unicode  Windows-1252
========================================= =======  ============
″ double prime                            U+2032      -
" quotation mark                          U+0022     0x22
ʺ modifier letter double prime            U+02BA      -
” right double quotation mark             U+201D     0x94

′ prime                                   U+2032      -
' apostrophe                              U+0027     0x27
´ acute accent                            U+00B4     0xb4
ʹ modifier letter prime                   U+02B9
Character                                 Unicode  Windows-1252
========================================= =======  ============
ᴀ Latin Letter Small Capital A            U+1D00      -
A Latin Capital Letter A                  U+0041     0x41
a Latin Small Letter A                    U+0061     0x61

ᴍ Latin Letter Small Capital M            U+1D0D      -
M Latin Capital Letter M                  U+004D     0x4d
m Latin Small Letter M                    U+006D     0x6d