【问题标题】:How to decode a QByteArray using UTF-8 with Latin-1 fallback如何使用带有 Latin-1 后备的 UTF-8 解码 QByteArray
【发布时间】:2014-11-11 23:31:00
【问题描述】:

我有一个连接到 IRC 服务器的套接字。我想将接收到的数据(QByteArray)转换为 QString。因为在 IRC 上,并不是每个人都使用 UTF-8,所以我想尝试使用 UTF-8 解码 QByteArray:

QString s = QString::fromUtf8(array);

问题在于 Qt 默默地替换“坏”字符并且总是返回一个 QString。我想“尝试”解码,如果无法正确解码,则回退到 latin-1 解码。

我该怎么做?

【问题讨论】:

    标签: c++ qt utf-8 qstring


    【解决方案1】:

    不幸的是,Qt 似乎没有提供解码例程来允许配置其处理无效序列。

    相反,您应该能够执行以下操作:

    QString s = QString::fromUtf8(array);
    if (s.toUtf8() != array) {
      s = QString::fromLatin1(array);
    }
    

    UTF-8 和 UTF-16 之间的直接转换(即无规范化)应该是无损且完全可逆的。如果从 UTF-16 转换为 UTF-8 不会产生原始数据,那是因为原始数据不是有效的 UTF-8。

    虽然在正常情况下不太可能,但某些其他编码的文本可能恰好是有效的 UTF-8,但在 UTF-8 与正确的编码中具有不同的含义。这样的文本将被检测为 UTF-8,并且不会按预期显示。避免这种情况的唯一方法是事先了解正确的编码,例如通过正确编码的协议声明。


    另一个选择是使用std::wstring_convert,它是 C++11 标准库的一部分。

    #include <codecvt> // for codecvt_utf8_utf16
    #include <locale>  // for wstring_convert
    
    QByteArray array = ...
    
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
    QString s;
    try {
      std::u16string s16 = converter.from_bytes(array.data(), array.size());
    
      s = QString::fromUtf16(s16.c_str());
    
    } catch(...) {
      s = QString::fromLatin1(array);
    }
    

    注意fromUtf16char16_t 的使用取决于this change,您使用的Qt 版本中可能不包含该this change。据推测,他们最终还会添加类似fromStdU16String() 的内容,因此您可以说QString::fromStdU16String(s16),或者可能添加隐式转换,因此您可以直接说s = s16;

    另请注意,libstdc++(gcc 的默认标准库实现)尚不包含此转换工具。 Visual Studio 2010 及更高版本有,libc++ 有。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多