【问题标题】:C++ encode string to Unicode - ICU libraryC++ 将字符串编码为 Unicode - ICU 库
【发布时间】:2011-04-12 21:06:15
【问题描述】:

我需要将 ISO-2022-JP 和 ISO-2022-JP-2(以及 ISO-2022 的其他变体)中的一堆字节转换为 Unicode。我正在尝试使用 ICU (link text),但以下代码不起作用。

std::string input = "\x1B\x28\x4A" "ABC\xA6\xA7";    //the first 3 chars are escape sequence to use JIS_X201 character set in GL/GR
UErrorCode status = U_ZERO_ERROR;
UConverter *conv;
// set up the converter
conv = ucnv_open("ISO-2022-JP", &status);
if (status != U_ZERO_ERROR) return false;   //couldn't find character set

UChar * convDest = new UChar[2*input.length()]; //ucnv_toUChars will use up to 2*length

// convert to Unicode
int resultLen = (int)ucnv_toUChars(conv, convDest, 2*input.length(), input.c_str(), input.length(), &status);

这不起作用。结果包含“?”我输入的任何字符都高于 ASCII。状态没有错误。我做错了什么?

最重要的是,我在编译库 4.4 版时遇到了问题,因为 MSVC 9 项目无法转换为 MSVC 10 项目。

我也知道 libiconv 开源库。我无法在 Windows 上编译那个。如果有人对其他图书馆有任何建议,也欢迎。

谢谢。

编辑 我最初使用的转义序列是错误的。所以现在ICU接受字符串,去掉转义序列——这是朝着正确方向迈出的一步。但结果仍然包含“?”字符。

EDIT2 我无法转换为 MSVC 10 项目的原因是未安装 x64 平台(默认情况下未安装)。或者,我可以在文本编辑器中打开所有项目并删除所有提及的 x64 目标。

【问题讨论】:

    标签: c++ c character-encoding icu


    【解决方案1】:

    这与 ISO 2022 编码不同。高位应该为零。转义序列看起来有点可识别,但它以 ESC 开头。 0x1b,而不是 0xb0。不知道这些字节值的真正含义。

    【讨论】:

    • 你是对的。转义顺序错误。愚蠢的错误。但是,我认为输入字符串对于 ISO 2022 是正确的。该标准支持 8 字节编码——这就是为什么你有 GL 和 GR 平面的原因。还要查看 ISO-2022-JP 的en.wikipedia.org/wiki/ISO/IEC_2022,考虑到转义序列,它应该绑定en.wikipedia.org/wiki/JIS_X_0201 字符集,它确实映射了更高的字节。我将这个参考用于 ISO-2022:ecma-international.org/publications/files/ECMA-ST/Ecma-035.pdf 第 8 节描述了 8 位代码。
    • 这是一个完整的编码漏洞,大约是我见过的最糟糕的编码。它对解码器状态非常敏感,请确保您使用来自已知良好来源的真实数据。如果您没有好的数据,一种方法是编码您希望首先看到的内容,然后将其推回解码器。
    • 我完全同意。绝对是一场噩梦。我会尽量确保我的意见是好的。
    【解决方案2】:

    (这个问题看起来很眼熟,你好。)

    一个小问题,小问题:您想使用if(U_FAILURE(status))(或相反,U_SUCCESS(status))检查错误状态。

    【讨论】:

      【解决方案3】:

      我无法使转换适用于 ISO-2022-JP 编码中的 JIS_X201 字符集。而且我无法使用我可以使用的任何工具生成“有效”的工具 - 尝试过 Java(ISO2022 的 ICU 和非 ICU 实现)和 C++。

      所以我基本上只是编写了一个函数来进行代码查找并使用此表转换为 Unicode:wikipedia

      编辑 当我开始填写错误报告时,我想包含 ISO-2022-JP 的 RFC。然后我在 RFC “The Kana set of JIS X 0201 is not used in ISO-2022-JP messages”中找到了这一行。 link text。所以看起来标准实际上并没有定义高位。 ISO-2022-JP-3 将映射高位,但映射到低平面。所以我必须取每个字节并从中减去 0x80,然后通过 ISO-2022-JP-3 传递,然后取其他字节

      所以严格来说,我会说这不是一个错误。不过,这是一个非常令人头疼的问题。

      附:我试图解码的整个混乱流来自 DICOM。请参阅pdf 第 107 页,了解他们认为可以接受的内容。

      【讨论】:

      • 非常有趣。您是否尝试过使用 Java(非 ICU)从 2022 年转换为 Unicode?​​span>
      • 我试过了: Charset iso2022JP = Charset.forName("ISO-2022-JP"); CharBuffer 结果 = iso2022JP.decode(ByteBuffer.wrap(bytes));其中字符集是 sun.nio.cs.ext.ISO2022_JP,结果与 ICU 相同。它基本上没有映射128以上的字符。
      • Budric 您能否在bugs.icu-project.org/trac/newticket 上提交有关ICU 的错误并提及这些发现?真的很奇怪,这些都不支持编码。
      • 嗯...因为另一个编码器做同样的事情它可能不是一个错误。请参阅上面的编辑。
      • 这不是错误。此输入序列: "\x1B\x28\x4A" "ABC\x1b\x28\x49\x26\x27" 产生:0041 0042 0043 FF66 FF67 我添加了 "(I" 以转移到片假名范围,并剥离关闭高位(A6/A7 -> 26/27)您链接的维基百科页面指出“例如,每个字节的最高有效位没有任何意义;这允许 ISO/IEC 2022(如 ISO/IEC 646)以便通过 7 位通信通道轻松传输。”以及 Ken Lunde 的 CJKV 书,其中陈述相同。使用 Jis X 201,但仅使用它的低 128 值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-27
      • 2020-06-16
      • 2014-01-29
      • 1970-01-01
      相关资源
      最近更新 更多