代码之家  ›  专栏  ›  技术社区  ›  R.. GitHub STOP HELPING ICE

如何最好地处理Windows的16位wchar\t丑陋?

  •  2
  • R.. GitHub STOP HELPING ICE  · 技术社区  · 14 年前

    wchar_t 是16位。

    1. 提供CESU-8环境而不是UTF-8。我真的不喜欢这个。
    2. 扩展包装器以替换mingw 世界卫生组织 具有 typedef int32_t wchar_t; 以及处理 WCHAR 世界卫生组织 与众不同。这是一个痛苦,但它可能是理想的移植应用程序,期待一个干净的POSIX类型的环境,不使用 世界卫生组织 用于任何Windows API目的。
    3. 以下黑客攻击:

    mbrtowc 输出a 读取4字节UTF-8字符的前3个字节后,对应于高代理项,并将剩余状态保持在 mbstate_t 对象。在接收到下一个字节时,它将其与保存的状态相结合以输出低位代理项。如果最后一个字节最终无效,它将返回-1(使用EILSEQ),并且输出流中会有一个单独的代理项(坏…)。

    wcrtomb 在处理高代理项时,输出UTF-8的前2个字节,并将剩余状态保存在其 对象。当它随后处理低位代理时,它将其与保存的状态相结合,以输出UTF-8的最后2个字节。如果没有收到有效的低代理项,它将返回-1(使用EILSEQ),并且输出流中会出现一个不完整的UTF-8序列(bad…)。

    这种方法的优点是,只要输入有效,它就可以工作,并允许访问任何UTF-8字符,从而访问应用程序可能需要处理的任何可能的文件名/参数等文本。

    缺点是它不严格符合isoc( 世界卫生组织 字符串不允许是有状态的),并且它会延迟对错误字符的检测,直到写入了不正确的部分输出。

    我正在寻找不同选择的反馈,尤其是我提出的黑客:是否合理,是否有可能造成严重错误的缺点,是否有任何其他缺点,我还没有考虑,这可能会使该计划无法完全运作。我也很高兴听到我没有想到的任何其他可能的解决办法。

    2 回复  |  直到 14 年前
        1
  •  1
  •   dan04    14 年前

    我会做类似于#4的操作,但是在确定输入有效之前不要生成任何输出。

    • mbrtowc 应该解码整个角色。如果它在BMP之外,则输出高代理项并将低代理项存储在 mbstate_t .
    • wcrtomb 应该把高代名词储存在 MBU状态 ,如果字符有效,则输出所有4个UTF-8字节。
        2
  •  0
  •   Chris Becke    14 年前

    如果您在windows上,您可以使用MultiByteToWideChar和WideCharToMultiByte在UTF-16和UTF-8之间一次转换一个完整的字符串。

    如果要避免使用Windows API(在Windows包装器代码中!)然后使用mbstowcs一次转换整个字符串。