【问题标题】:String conversion from UTF-8 to UTF-16 Big endian is failing (using C, C++ language)从 UTF-8 到 UTF-16 Big endian 的字符串转换失败(使用 C、C++ 语言)
【发布时间】:2011-05-07 14:50:46
【问题描述】:

我正在使用 g_convert() glib 函数将 utf-8 字符串转换为 utf-16 大端字符串。转换失败。我们收到一条错误消息,提示“不支持转换”

有人可以提供解决此问题的线索吗?

谢谢

以下是用于将字符串从 UTF-8 转换的代码。转为 UTF16 Bigendian

unsigned short *result_str;

gsize bytes_read, bytes_written;

gssize len = 0;

GError *error = NULL;

result_str = (unsigned short *)g_convert("text data", len, "UTF-16BE", "UTF-8", &bytes_read, &bytes_written, &error);

【问题讨论】:

  • 我不熟悉它,但作为一个实用的解决方案,转换为小端 utf-16 然后只是字节交换怎么样?或者,查找 utf-8 编码算法,例如维基百科。有时 DIY 比让别人的代码工作更容易。 :-)
  • 您能否发布一段最少的代码来显示您遇到的问题?问题的可能原因有很多,有一小段代码显示问题有助于消除一些可能性。
  • 我总是想知道这些想将 转换为 UTF-16 的人。你会认为他们中的大多数人都想反其道而行之:毕竟,你在 UTF-8 中看到了多少网页?现在 UTF-16 有多少? '

标签: c++ c utf-8 glib utf-16


【解决方案1】:

You len 为 0。GLib manual 表示 len 必须为 -1 才能以 NULL 结尾的字符串。

【讨论】:

    【解决方案2】:

    g_convert 在底层使用 iconv。

    在我的机器上使用 cygwim 我可以做到

    iconv -l 
    

    其中列出了支持的编码,但 UTF-16BE 确实出现在列表中:-

    $ iconv -l | grep BE
    UCS-2BE UNICODE-1-1 UNICODEBIG CSUNICODE11
    UCS-4BE
    UTF-16BE
    UTF-32BE
    
    James@XPL3KWK28 ~
    $ iconv -f UTF-8 -t UTF16-BE
    iconv: conversion to UTF16-BE unsupported
    iconv: try 'iconv -l' to get the list of supported encodings
    

    如您所见,它不支持与 UTF-8 之间的转换。

    您可能需要分两个阶段执行此操作,从 UTF-8 到 UTF-16,然后从 UTF-16 到 UTF-16BE。

    【讨论】:

    • iconv -l | grep BE EBCDIC-BE// EBCDIC-CP-BE// UCS-2BE// UCS-4BE// UTF-16BE// UTF-32BE// UTF16BE// UTF32BE//
    • 支持从 UTF-8 到 UTF-16BE 的转换。但不知道为什么我会收到这个错误..
    • 可能支持单独的代码页,但不支持从任何特定代码页到另一个代码页的转换。
    【解决方案3】:

    我怀疑g_convert 不支持UTF-16BE(基于错误消息)。不过,将 UTF-8 转换为 UTF-16BE 很简单(没有表格或其他类似的垃圾)——您可以自己进行转换。

    您可能还想检查是否支持UTF-16,并在必要时进行自己的字节交换。但我也不相信g_convert 支持UTF-16

    【讨论】:

      【解决方案4】:

      您的系统似乎不支持该转换。 (这个错误意味着 iconv() 返回了 EINVAL。)

      在我的 Linux 系统上似乎确实支持它:

      echo "Hello" | iconv --from-code UTF-16BE --to-code UTF-8
      

      (显然“Hello”不是一个有效的 UTF-16 字符串,但它确实会被转换成某种东西,所以似乎支持实际的转换)

      查看“iconv --list”中是否有UTF-16BE

      在这种特殊情况下,您最简单的解决方案可能是只使用 g_utf8_to_utf16(): http://library.gnome.org/devel/glib/stable/glib-Unicode-Manipulation.html#g-utf8-to-utf16

      您可以轻松地编写自己的字节交换、未经测试的代码:

      if (G_BYTE_ORDER != G_BIG_ENDIAN) {
        for (i = 0; i < len; ++i) {
          result_str[i] = GUINT16_TO_BE(result_str[i]);
        }
      }
      

      【讨论】:

      • "iconv --list" 在我的系统上有 UTF-16BE
      • 其实有2个:UTF-16BE,UTF16BE。这两者有什么区别吗?
      • 我怀疑这两种拼写有区别。可能 iconv 支持编码但不支持从 UTF-8 转换,或者您的 glib 或 C 库安装可能有其他问题。
      • 如果您发布了一个小的可编译测试用例,人们可以在他们的系统上试用它,并让您知道这个问题是否特定于您的系统。
      猜你喜欢
      • 2011-09-06
      • 2014-02-05
      • 2023-04-03
      • 2014-02-22
      • 2016-05-31
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      相关资源
      最近更新 更多